在前端页面中如果有文件或者图片需要上传的场景下,通用做法是使用`formdata`将文件从前端传输到后台,在后台上传文件并将url保存在数据库。 当前项目是使用`vue` + `Element UI` + `django` 的框架,需要将文件从vue传递到django中,上传阿里云OSS存储。记录使用方法

在前端页面中如果有文件或者图片需要上传的场景下,通用做法是使用 formdata 将文件从前端传输到后台,在后台上传文件并将url保存在数据库。
当前项目是使用 vue + Element UI + django 的框架,需要将文件从vue传递到django中,上传阿里云OSS存储。记录使用方法

formdata的简单使用

新建一个formdata的变量

var data = new FormData() 
    data.append('name', this.createForm.name)
    data.append('desc', this.createForm.desc)
    data.append('page_url', this.createForm.page_url)
    data.append('edit', this.createForm.edit)
    data.append('page_id', this.createForm.page_id)

通过append(key, value)来添加数据,这里分为两种情况,
一、key值无重复
key值不存在重复的情况下,一个key对应一个value

data.append('name', this.createForm.name)
data.append('desc', this.createForm.desc)

二、key值重复
key值在某些时候会重复,如上传多个文件时,这时一个key对应一个数组,数组中为多个value

data.append('file', file.raw)
data.append('file', file.raw)

key值对应一个value,可以通过get方法取值

data.get(key)

key值对应多个value,可以通过getAll方法取值

data.getAll(key)

如果key对应多个value而使用get取值,只能取到value的最后一个值

判断数据是否存在

我们可以通过has(key)来判断是否对应的key值

data.has('name')

通过delete(key),来删除数据

data.delete('name')

我们可以通过entries()来获取一个迭代器,然后遍历所有的数据,

formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k2", "v1");
var i = formData.entries();
i.next(); // {done:false, value:["k1", "v1"]}
i.next(); // {done:fase, value:["k1", "v2"]}
i.next(); // {done:fase, value:["k2", "v1"]}
i.next(); // {done:true, value:undefined}

项目中使用

要完成的功能如下,在一个弹出框中能够输入信息,重点是能够添加多个文件。

Element UI中已经处理好,当选择多个文件之后,会保存到一个数组中,我只需要对这个数组操作即可。

vue代码

创建formdata

var data = new FormData();
// 普通变量
data.append('name', this.createForm.name)
data.append('desc', this.createForm.desc)
data.append('page_url', this.createForm.page_url)
data.append('edit', this.createForm.edit)
data.append('page_id', this.createForm.page_id)
// 文件。因为涉及到编辑功能,所以对于新上传的文件保存其`file.raw`,编辑的文件保存文件id
this.createForm.file.forEach((file) => {
  if (file.raw) {
    data.append('new_files', file.raw)
  }else{
    data.append('old_files', file.page_file_id)
pageCreate(data).then((res) => {
........
export function pageCreate(form) {
    return postForm(URL.createUrl, form)

post请求的内容格式。post请求不是普通的json而是form-data

export function postForm (url, data= {}) {
  return new Promise((resolve, reject) => {
    axios.create({
      withCredentials: true,
      headers: {'X-CSRFToken': getCookie('csrftoken'), 'Content-Type':  "multipart/form-data"},
    }).post(url, data).then(response => {
      resolve(response.data)
    }, err => {
      reject(err)

django的接收:

# 接收到formdata的出文件之外的数据
data = request.POST
# 接收文件,getlist是接收多个文件
# formdata在vue中同一个key传入了多个value,value成为了一个数组,所以需要使用getlist来获取所有文件
new_files = request.FILES.getlist('new_files')
# formdata在vue中同一个key只有一个文件类型的value,可以使用get来获取文件
new_files = request.FILES.get('file')

后续将文件上传到阿里云的对象存储,将文件的url保存到数据库。展示或编辑文件时,只需要传入文件的url,element UI即可解析出文件。