前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs服务器如何接收前端传递的文件

nodejs服务器如何接收前端传递的文件

作者头像
挥刀北上
发布2019-07-19 15:46:39
14.7K0
发布2019-07-19 15:46:39
举报
文章被收录于专栏:Node.js开发

之前发过用nodejs搭建静态服务器的文章,今天和大家探讨一下如何利用nodejs接收前端上传的文件。

首先我们用nodejs的原生http模块搭建一个服务器,并且利用data事件和end事件接收前端上传的数据,代码演示如下:

代码语言:javascript
复制
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文件中。

看一下前端代码,简单的一个上传文件的表单:

代码语言:javascript
复制
<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文件,截图如下:

上面红色部分就是图片信息转换为utf-8字符串后的编码,但是我们要图片,不要乱码,怎么办呢?

我们需要将这部分乱码截取出来,再根据图片的格式写入到一个图片文件中就可以了,我们需要做的是,我们要提取图片的二进制信息,提取图片描述信息(大小、名称、格式),将图片输出到需要长久保存的位置,自己手动实现的话比较麻烦。

这部分逻辑已经有一些npm包帮咱们实现了,今天就介绍两个常用的。

首先看第一个npm包,也是我感觉最好用的,fromidable,我们集成formidable将上面服务器的代码升级为第二个版本,代码如下:

代码语言:javascript
复制
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的使用非常简单,以上代码主要作用如下:

1、构造form对象

2、配置相关参数,比如长久保存文件的位置,上传文件大小限制,是否允许上传图片数组。

3、调用form对象的parse方法解析文件信息,文件信息解析完成后会挂载到req上,文本信息将挂载到fileds上,文件信息将挂载到files上面。

4、根据fileds和files信息实现后端逻辑

5、将文件长久保存的地址返回给前端

比原生实现文件上传简单了很多,而且可以根据需求配置不同的设置,formidable的常用配置如下:

代码语言:javascript
复制
new一个form实例
var form = new formidable.IncomingForm()

将请求信息编码设置为utf-8
form.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的一个中间件,express1、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的使用方式很不一样,使用步骤大致如下:

1、引入npm包multer,用一个变量来接受,假设变量为multer

2、multer为一个函数,这个函数调用后会返回一个对象,我们用upload来接受这个对象,这个对象上面有好多生成express中间件的方法。

3、用upload这个生成中间件,放在相应位置去调用。

演示代码如下:

代码语言:javascript
复制
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中间件的配置分为两步:

1、第一步先调用multer函数传递一些参数,生成一个中间件生成对象

2、对象在调用特定方法传入特定参数,最终生成定制化的中间件。

那这样的话,我们想要熟练使用multer的话就需要知道

1、multer函数调用时需要传递哪些参数。

2、中间件生成对象有哪些方法可以调用,并且需要传递哪些参数。

multer不同于formidbale的地方在于multer将所有接收到的信息都挂载到了req.body和req.file上面。

下面我们就按照是上面提到的两个问题,梳理一下multer的文档,首先看第一个问题,multer需要传递哪些参数:

1、dest or storage 在哪里存储文件,dest比较直接,sotrage是存储引擎,我们可以灵活的配置存储引擎将文件进行保存 一般情况下,使用dest即可,像这样: var upload = multer({ dest: 'uploads/' })

2、fileFilter 设置一个函数来控制什么文件可以上传以及什么文件应该跳过,这个函数应该看起来像这样:

代码语言:javascript
复制
function fileFilter (req, file, cb) {

  // 这个函数应该调用 `cb` 用boolean值来
  // 指示是否应接受该文件

  // 拒绝这个文件,使用`false`,像这样:
  cb(null, false)

  // 接受这个文件,使用`true`,像这样:
  cb(null, true)

  // 如果有问题,你可以总是这样发送一个错误:
  cb(new Error('I don\'t have a clue!'))

}

3、limits 限制上传的数据,是一个对象有如下可选项可供使用:

以上便是multer的参数,接下来看一下multer生成的中间件生成对象有哪些方法:

1、 .single(fieldname)

接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file。

2 、.array(fieldname[, maxCount])

接受一个以 fieldname 命名的文件数组。可以配置 maxCount 来限制上传的最大数量。这些文件的信息保存在 req.files。

3、 .fields(fields)

接受指定 fields 的混合文件。这些文件的信息保存在 req.files。fields 应该是一个对象数组,应该具有 name 和可选的 maxCount 属性。

代码语言:javascript
复制
Example:
[

{ name: 'avatar', maxCount: 1 },

{ name: 'gallery', maxCount: 8 }

]

4、.none()

只接受文本域。如果任何文件上传到这个模式,将发生 "LIMIT_UNEXPECTED_FILE" 错误。这和 upload.fields([]) 的效果一样。

5、.any()

接受一切上传的文件。文件数组将保存在 req.files。

当然了使用multer我们一样要注意:永远不要将 multer 作为全局中间件使用,因为恶意用户可以上传文件到一个你没有预料到的路由,应该只在你需要处理上传文件的路由上使用。

以上便是multer的使用了,multer还有很多其他使用方式这里没有全部展示出来,毕竟篇幅有限,看文章读到这里的一定是真爱无疑了,小编一开始考虑将multer拆分出去的,但是这两个玩意儿本来就一实现同一个功能的,研究的话干脆就全研究了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nodejs全栈开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档