Multer
是一个node.js中间件,用于处理 multipart/form-data类型的表单数据,主要用于上传文件。只处理 multipart/form-data 类型的表单数据。
Multer是基于Busboy解析的文件参数信息,获取fileStream,并通过storage转存的file.stream.pipe(outStream) //file.stream即fileStream
Multer在解析完请求体后,会向Request对象中添加一个body对象和一个file或files对象(上传多个文件时使用files对象 )。其中,body对象中包含所提交表单中的文本字段(如果有),而file(或files)对象中包含通过表单上传的文件。
multer(options).single(name)
上传单个文件内容,如一次只上传一张图片。name为上传文件时的参数字段名称。
multer(options).array(name[,maxCount])
适用于同一个字段,一次上传多个文件的情况,例如选择多张图片发送。接受一个以 name 命名的文件数组。可以指定 maxCount 来限制上传的最大数量。这些文件的信息保存在 req.files。
multer(options).fields(fields)
适用于上传多个字段的情况。接受指定 fields 的混合文件。这些文件的信息保存在 req.files。fields 是一个对象数组,具有 name 和可选的 maxCount 属性。
multer(options).none()
接收只有文本域的表单,如果上传任何文件,会返回 “LIMIT_UNEXPECTED_FILE” 错误。
multer(options).any()
接收一切上传的文件。
Multer 接受一个 options 对象,其中最基本的是 dest/storage 属性,这将告诉 Multer 将上传文件保存在哪。如果省略 options 对象,这些文件将保存在内存中,永远不会写入磁盘。
1.dest:指定上传文件的存储路径。文件名默认为随机字符。如果想自定义文件名称,使用storage属性代替dest
2.storage:指定上传文件的存储路径和文件名称。
2-1.DiskStorage 磁盘存储引擎
磁盘存储引擎可以让你控制文件的存储。有两个属性,属性值都是函数。destination,指定文件存储的路径;filename,指定文件的存储名称。
multer({storage: multer.diskStorage({
//设置存储路径
destination:(req,file,cb)=>{
console.log("destination:",file);//打印结果如下图
cb(null,fullPath);
},
//设置存储的文件名
filename:(req,file,cb)=>{
console.log("filename:",file);//打印结果如下图
//获取文件的扩展名
let extname=path.extname(file.originalname);
filename=file.fieldname+"-"+Date.now()+extname;
cb(null,filename);
}
})
});
2-2.MemoryStorage 内存存储引擎
multer({storage: multer.memoryStorage()})
3.limits: 用来指定一些数据大小的限制等
limits:{
files:2, //最多上传2个文件
fileSize:5120 //设置单个文件最大为 5kb
}
4.fileFilter
fileFilter 为一个函数,用来控制什么文件可以上传以及什么文件应该跳过。
function fileFilter (req, file, cb) {
// 通过调用cb,用boolean值来指示是否应接受该文件
// 拒绝这个文件,使用`false`,像这样:
cb(null, false)
// 接受这个文件,使用`true`,像这样:
cb(null, true)
// 如果有问题,你可以总是这样发送一个错误:
cb(new Error('I don\'t have a clue!'))
}
Busboy
用于解析传入的HTML表单数据的node.js模块。
let Busboy = require('busboy');
//通过请求头信息创建busboy对象 headers - 这些是传入请求的 HTTP 标头,由各个解析器使用 preservePath - 是否应保留请求中文件部分的文件名中的路径 limits - 对传入数据的各种限制
let busboy = new Busboy({ headers: req.headers });
//将流链接到busboy对象
req.pipe(busboy);
//此事件由找到的每个文件字段发出
busboy.on('file', function (filedname, file, filename, encoding, mimetype) {//(字段名,文件,文件名,传输编码,mime类型)
//创建一个可写流
let writeStream = fs.createWriteStream('./upload/' + filename);
//监听data事件,接收传过来的文件,如果文件过大,此事件将会执行多次,此方法必须写在file方法里
file.on('data', function (data) {
writeStream.write(data);
})
//监听end事件,文件数据接收完毕,关闭这个可写流
file.on('end', function (data) {
writeStream.end();
});
});
//监听finish完成事件,完成后重定向到百度首页
busboy.on('finish', function () {
res.writeHead(303, { Connection: 'close', Location: 'http://www.baidu.com/' });
res.end();
});
});
//此事件由找到的每个新的非文件字段发出
busboy.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: %j`, val);
});