题图 By Clm From Bingjavascript
以前发过用nodejs搭建静态服务器的文章,今天和你们探讨一下如何利用nodejs接收前端上传的文件。前端
首先咱们用nodejs的原生http模块搭建一个服务器,而且利用data事件和end事件接收前端上传的数据,代码演示以下:java
const http = require("http");const app = http.createServer();const fs= require("fs");app.on("request",(req,res)=>{ if(req.method=="POST"){ var data = []; req.on("data",(chunk)=>{ data.push(chunk) }) req.on("end",()=>{ var buffer = Buffer.concat(data); fs.writeFile("./a",buffer,(err)=>{ if(!err){ res.end("ok") } }) }) }})app.listen(3000,()=>{ console.log("ok");})
阅读源码,咱们发现这段脚本将上传的文件信息,写入到了当前目录的a文件中。node
看一下前端代码,简单的一个上传文件的表单:typescript
<body> <form action="http://localhost:3000/" method="POST" enctype="multipart/form-data"> <input multiple type="file" name="a"> <input type="submit" value="提交"> </form> <script> </script></body>
点击上传后,服务端将接收到的全部信息写入到了a文件中,打开a文件,截图以下:
express
上面红色部分就是图片信息转换为utf-8字符串后的编码,可是咱们要图片,不要乱码,怎么办呢?npm
咱们须要将这部分乱码截取出来,再根据图片的格式写入到一个图片文件中就能够了,咱们须要作的是,咱们要提取图片的二进制信息,提取图片描述信息(大小、名称、格式),将图片输出到须要长久保存的位置,本身手动实现的话比较麻烦。json
这部分逻辑已经有一些npm包帮我们实现了,今天就介绍两个经常使用的。后端
首先看第一个npm包,也是我感受最好用的,fromidable,咱们集成formidable将上面服务器的代码升级为第二个版本,代码以下:数组
const http = require("http");const app = http.createServer();const formidable = require("formidable");const path = require("path");app.on("request",(req,res)=>{ if(req.method=="POST"){ var form = new formidable.IncomingForm(); form.keepExtensions = true; form.multiples = true; console.log(form.type); form.uploadDir =path.join(__dirname,"my"); form.parse(req,function(err,fields,files){ res.end(JSON.stringify({fields,files})) }) }})app.listen(3000,()=>{ console.log("ok");})
仔细阅读源码,咱们发现formidable的使用很是简单,以上代码主要做用以下:
一、构造form对象
二、配置相关参数,好比长久保存文件的位置,上传文件大小限制,是否容许上传图片数组。
三、调用form对象的parse方法解析文件信息,文件信息解析完成后会挂载到req上,文本信息将挂载到fileds上,文件信息将挂载到files上面。
四、根据fileds和files信息实现后端逻辑
五、将文件长久保存的地址返回给前端
比原生实现文件上传简单了不少,并且能够根据需求配置不一样的设置,formidable的经常使用配置以下:
new一个form实例var form = new formidable.IncomingForm()
将请求信息编码设置为utf-8form.encoding = 'utf-8';
设置文件的临时存储存储路径,若是不设置的话默认设置到 os.tmpdir()form.uploadDir = "/my/dir";
nodejs会默认将文件信息保存在一个没有后缀的文件中,设置为true将保留后缀form.keepExtensions = false;
<!-- 未知待测试 -->Either 'multipart' or 'urlencoded' depending on the incoming request.form.type
设置上传信息-文本信息(fields)的的最大限制,默认是20mb,超出后会触发form上的error事件form.maxFieldsSize = 20 * 1024 * 1024;
设置上传信息-文件信息(file)的的最大限制,默认是200mb,超出后会触发form上的error事件form.maxFileSize = 200 * 1024 * 1024;
设置上传字符串的最大长度值为1000;form.maxFields = 1000;
若是须要对上传的文件进行校验,须要设置sha1和md5,默认不校验;form.hash = false;
若是前端表单设置了multiples,这个值须要设置为true,后端接收的文件为一个数组;form.multiples = false;
解析上传的数据,将文本字段和文件从req中提取出来,fields存储文本,files存储文件form.parse(req, function(err, fields, files) { // ...});
以上即是今天介绍的nodejs上传文件的第一个npm经常使用包formadable。
这个包也能够结合express使用,由于express是对原生http模块的封装,因此咱们可使用form.parse直接解析express路由中的req信息,从而获得前端传递的文件,或者结合express的中间件express-formidable,具体功能就不演示了,原理很是简单,就是将formidable封装成了一个express中间件而已,你们有兴趣能够去读一下文档。
接着看第二个经常使用的npm包,multer,这个插件是express的一个中间件,express一、2版本中原本是集成到express中的,express3以后就分离出来了,因此要使用multer必须会使用express,这也是为何把multer放到后面来说(小编真是用心良苦,今晚加鸡腿)。
首先咱们打开multer的npm官网,先看他的自我介绍:
Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. It is written on top of busboy for maximum efficiency. NOTE: Multer will not process any form which is not multipart (multipart/form-data)
https://www.npmjs.com/package/multer
翻译成中文就是,multer只负责解析表单数据,也就是请求头中携带content-type:multipart/form-data信息的请求才会处理,不然请注意multer不会运行。(小编的英语水平如何?)
multer的使用方式和formidable的使用方式很不同,使用步骤大体以下:
一、引入npm包multer,用一个变量来接受,假设变量为multer
二、multer为一个函数,这个函数调用后会返回一个对象,咱们用upload来接受这个对象,这个对象上面有好多生成express中间件的方法。
三、用upload这个生成中间件,放在相应位置去调用。
演示代码以下:
var express = require('express');var multer = require('multer');// 生成一个对象,凡是用这个对象生成的中间件,文件都会保存到uploads文件中var upload = multer({ dest: 'uploads/' })// 生成中间件,只能处理avatar的文件,文件的name只能是avatar,不是的话会报错var dealavatar = upload.single('avatar');var app = express()// 调用中间件app.post('/', dealavatar, function (req, res, next) { // req.file is the `avatar` file // req.body will hold the text fields, if there were any res.send({ fileds:req.body, files:req.file })})app.listen(3000,()=>{ console.log("ok");})
仔细阅读源码和注释,咱们发现,multer中间件的配置分为两步:
一、第一步先调用multer函数传递一些参数,生成一个中间件生成对象
二、对象在调用特定方法传入特定参数,最终生成定制化的中间件。
那这样的话,咱们想要熟练使用multer的话就须要知道
一、multer函数调用时须要传递哪些参数。
二、中间件生成对象有哪些方法能够调用,而且须要传递哪些参数。
multer不一样于formidbale的地方在于multer将全部接收到的信息都挂载到了req.body和req.file上面。
下面咱们就按照是上面提到的两个问题,梳理一下multer的文档,首先看第一个问题,multer须要传递哪些参数:
一、dest or storage 在哪里存储文件,dest比较直接,sotrage是存储引擎,咱们能够灵活的配置存储引擎将文件进行保存 通常状况下,使用dest便可,像这样: var upload = multer({ dest: 'uploads/' })
二、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!'))
}
三、limits 限制上传的数据,是一个对象有以下可选项可供使用:
以上即是multer的参数,接下来看一下multer生成的中间件生成对象有哪些方法:
一、 .single(fieldname)
接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file。
2 、.array(fieldname[, maxCount])
接受一个以 fieldname 命名的文件数组。能够配置 maxCount 来限制上传的最大数量。这些文件的信息保存在 req.files。
三、 .fields(fields)
接受指定 fields 的混合文件。这些文件的信息保存在 req.files。fields 应该是一个对象数组,应该具备 name 和可选的 maxCount 属性。
Example:[
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]
四、.none()
只接受文本域。若是任何文件上传到这个模式,将发生 "LIMIT_UNEXPECTED_FILE" 错误。这和 upload.fields([]) 的效果同样。
五、.any()
接受一切上传的文件。文件数组将保存在 req.files。
固然了使用multer咱们同样要注意:永远不要将 multer 做为全局中间件使用,由于恶意用户能够上传文件到一个你没有预料到的路由,应该只在你须要处理上传文件的路由上使用。
以上即是multer的使用了,multer还有不少其余使用方式这里没有所有展现出来,毕竟篇幅有限,看文章读到这里的必定是真爱无疑了,小编一开始考虑将multer拆分出去的,可是这两个玩意儿原本就一实现同一个功能的,研究的话干脆就全研究了。
持续不断的提供优质干货、心得、坚持作通俗易懂的技术订阅号。
本文分享自微信公众号 - nodejs全栈开发(geekclass)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。