FormData同时传输多个文件和其他数据

近日有个需求是:在web的对话框中,用户可以输入文本内容和上传附件,附件的数量不限,所有附件总和大小不超过20M。

这个实现的方法不止一种,比如之前的后端同事是要求:文件和文本分开传输,文件用一个单独接口上次,上传成功后返回一个id,把这个id和文本一起在另外一个接口传给后端就行了,后端会根据那个id去找对应的文件,这种实现是比较简单的,好多upload组件(比如elemenUI plus、arco-design、ant design之类的UI组件)都能支持上传文件。

不过这次合作的后端同事要求的是就一个接口,文件和文本一起用 FormData 传输给后端。

FormData 是什么呢?

MDN 中对 FormData 的介绍:
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 “multipart/form-data”,它会使用和表单一样的格式。
如果你想构建一个简单的GET请求,并且通过的形式带有查询参数,可以将它直接传递给URLSearchParams。
实现了 FormData 接口的对象可以直接在for…of结构中使用,而不需要调用entries() : for (var p of myFormData) 的作用和 for (var p of myFormData.entries()) 是相同的。

FormData 构造函数 FormData():

 new FormData();
 FormData.append()   // 向 FormData 中添加新的属性值

接下来看看实现:


//  upload 组件获取文件列表就不写了,暂定这里获得 文件列表 fileList: [ ]
const allFileMaxListSize = 20971520, // 所有上传文件的大小 20M(20*1024*1024)
const fileFormData = new FormData();
let totalFileSize = 0;
// 这里我用的是 forEach 循环 append 添加,也可以不用 forEach 自己说手动 多次 append,根据自己的需求
fileList?.forEach((item: any) => {
   fileFormData.append('files', item.file); 
    totalFileSize += item.file.size;
  });
  
// 注释!!!!这里为什么可以循环给 fileFormData.append('files', item.file); 因为 向 FormData 中添加新的属性值,FormData 对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。

if (totalFileSize > data.allFileMaxListSize) {
        alert('上传文件总和超过20M!');
      } else {
        const value = `${这里是文本的数据}`;
        fileFormData.append('txt', value);
        fileFormData.append('id', current);  // 如果当前修改数据的id,这行可有可无看具体情况
        try {
          commitComment(String(ticketId), fileFormData);  // 发送请求
         fileList = [];  // 清空
          alert('提交成功!');
        } catch {
          alert('error');
        }
      }

所以核心关键是这一句:

FormData同时传输多个文件和其他数据_第1张图片

希望本文对您有所帮助!

你可能感兴趣的:(js,前端,javascript,formdata)