FormData全解析及多文件上传前后端案例实战

这几天做项目都是个文件流各种打交道,当然其中就免不了和FormData接触了了呀,所以这次仔细研读下FormData类的所有常用的特性,以及总结所用的领域有哪些?

一、案例分析(热身)

在了解FormData之前先来了解一个前端上传多个附件,且能对上传的附件进行删除,后端用express、multer接受处理文件的小案例,此案例涉及的一些技术栈:node、express、fetch、FormData、multer

FormData全解析及多文件上传前后端案例实战_第1张图片

FormData全解析及多文件上传前后端案例实战_第2张图片

前端业务核心逻辑:

var formData = new FormData();

files.forEach(v => {
    formData.append('files',v,v.name);
});
formData.append('user','ligc');

fetch('/upload',{
    method: 'post',
    body: formData
}).then(res=> res.json()).then(res=>{
    console.log(res);
});

后端核心业务逻辑:

// 获取上传文件
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    cb(null, Math.random().toString().split('.').join('') + '-' + file.originalname)
  }
});
const upload = multer({ storage: storage });
app.post('/upload',upload.array('files'), (req,res) => {
    res.json({status:200,code:0,data:req.body,message:'上传文件成功'});
});


遇到的问题有哪些?

1.通过express默认的req.files接收为undefined
2.fetch请求不能设置headers的Content-type=multipart/form-data,如果设置,则后端不能接收到文件信息
3.使用multer生成附件的时候,没有文件后缀
4.Express打开网页文件的方式,可以选择express.static的方式打开

参考文档:

https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
https://juejin.im/post/59eb064d51882578d84e9a39
https://segmentfault.com/a/1190000012918178
https://www.jianshu.com/p/1e92a86c571a

 

前端所有代码:




    
    多文件上传测试
    
      
    
    




支持上传多个文件

后端所有代码:

const express = require('express');
const app = express();
const multer = require("multer");

// 获取上传文件
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    cb(null, Math.random().toString().split('.').join('') + '-' + file.originalname)
  }
});
const upload = multer({ storage: storage });
app.post('/upload',upload.array('files'), (req,res) => {
    res.json({status:200,code:0,data:req.body,message:'上传文件成功'});
});


app.use('/web',express.static('html'));

app.listen(3000, () => {
    console.log('server start at port 3000.');
});

二、FormData对象

概述:FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。如果表单enctype属性设为multipart/form-data ,则会使用表单的submit()方法来发送数据,从而,发送数据具有同样形式。

注:FormData 对象的字段类型可以是 Blob, File, 或者 string: 如果它的字段类型不是Blob也不是File,则会被转换成字符串。

1. 使用FormData发送表单数据

(包括文件信息,所有的输入元素都需要有name属性,否则无法访问到值。)

var formElement = document.querySelector("form");
var formData = new FormData(formElement);
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
formData.append("serialnumber", serialNumber++);
request.send(formData);

2. FormData方法详解

(1)append() 方法 * 常用
 
概述:添加一个新值到 FormData 对象内的一个已存在的键中,如果键不存在则会添加该键。

语法:

formData.append(name, value);
formData.append(name, value, filename);

参数:name -> 表单name,value -> 表单value,filename -> 传给服务器的文件名称 ,当一个 Blob 或 File 被作为第二个参数的时候, Blob 对象的默认文件名是 "blob"。 File 对象的默认文件名是该文件的名称。

示例:

var formData = new FormData(); // Currently empty
formData.append('username', 'Chris');
formData.append('userpic', myFileInput.files[0], 'chris.jpg');


(2)set() 方法

概述:set() 方法会对 FormData 对象里的某个 key 设置一个新的值,如果该 key 不存在,则添加。(set() 和 FormData.append 不同之处在于:如果某个 key 已经存在,set() 会直接覆盖所有该 key 对应的值,而 FormData.append 则是在该 key 的最后位置再追加一个值。)

语法:

formData.set(name, value);
formData.set(name, value, filename);

示例:

var formData = new FormData(); // Currently empty
formData.set('username', 'Chris');
formData.set('userpic', myFileInput.files[0], 'chris.jpg');

(3)get() 方法

概述:FormData的get()方法用于返回FormData对象中和指定的键关联的第一个值,如果你想要返回和指定键关联的全部值,那么可以使用getAll()方法。

语法:

formData.get(name); // 返回值为 键名对应的第一个键值

示例:

var formData = new FormData();
formData.append('username', 'Chris');
formData.append('username', 'Bob');
formData.get('username'); // Returns "Chris"

(4)getAll() 方法

概述:getAll()方法会返回该 FormData 对象指定 key 的所有值。

示例:

var formData = new FormData();
formData.append('username', 'Chris');
formData.append('username', 'Bob');
formData.get('username'); // Returns ["Chris", "Bob"]


(5)entries() 方法

概述:The FormData.entries() 方法返回一个 iterator对象 ,此对象可以遍历访问FormData中的键值对。其中键值对的key是一个 USVString 对象;value是一个 USVString , 或者 Blob对象。

语法:

formdata.entries(); // 返回 iterator

示例:

var formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');

// Display the key/value pairs
for(var pair of formData.entries()) {
   console.log(pair); // ["key1", "value1"]、["key2", "value2"]
   console.log(pair[0]+ ', '+ pair[1]); 
}

(6)keys() 方法

概述:FormData.keys() 该方法返回一个迭代器(iterator),遍历了该 formData  包含的所有key ,这些 key 是 USVString 对象。

语法:

formdata.keys();  // 返回一个迭代器( iterator)

示例:

// 先创建一个 FormData 对象
var formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');

// 输出所有的 key
for (var key of formData.keys()) {
   console.log(key); // key1 key2
}

(7)has() 方法 [ Boolean formData.has(name); ]

示例:

formData.has('username');  // returns false
formData.append('username', 'Chris');
formData.has('username');  // returns true

(8)values() 方法 [ 类似format.keys(),获取所有values  ]

(9)delete() 方法 [formData.delete(name); // return undefined; ]

概述:delete() 方法 会从 FormData 对象中删除指定 key 和它对应的 value(s)。


 

你可能感兴趣的:(node,javascript,express)