Nodejs实现文件上传的示例代码


Posted in NodeJs onSeptember 26, 2017

笔者用nodejs做项目时需要用到文件上传的功能,在网上搜索了很多教程,找到了一个express的中间件,用于处理 multipart/form-data 类型的表单数据,可以很方便的将表单中的文件数据保存到服务器。

介绍

简单的用法

定义存储器

Multer作为express的一个中间件,我们可以很方便的自定义上传的文件目录以及保存的文件名。先看一个最简单的用法, demo1地址 :

var express = require('express');
var multer = require('multer');
var app = express();

var upload = multer({
  storage: multer.diskStorage({
    destination: function (req, file, cb){
      cb(null, './uploads/');
    },
    filename: function (req, file, cb){
      //file.originalname上传文件的原始文件名
      var changedName = (new Date().getTime())+'-'+file.originalname;
      cb(null, changedName);
    }
  })
});

我们先创建了一个upload对象,这个对象中destination函数用来定义上传文件的存储的文件夹;filename函数用来修改上传文件存储到服务器的文件名称,这里我们我们加上一个时间戳简单区分一下。这两个函数都是通过回调函数来实现的。每次上传的时候这两个函数都会调用一次,如果是多个文件上传,那个这两个函数就调用多次,调用顺序是先调用destination,然后调用filename。

在两个函数中都会有一个 file 对象,表示当前上传的文件对象,有以下几个属性:

  • fieldname:上传的字段名
  • originalname:上传的文件名
  • encoding:文件的编码类型
  • mimetype:文件的MIME类型

定义路由回调

//单个文件上传
app.post('/upload/single',upload.single('singleFile'),(req,res)=>{
  console.log(req.file);
  res.json({
    code: '0000',
    type:'single',
    originalname: req.file.originalname
  })
});

//多个文件上传
app.post('/upload/multer',upload.array('multerFile'),(req,res)=>{
  console.log(req.files);
  let fileList = [];
  req.files.map((elem)=>{
    fileList.push({
      originalname: elem.originalname
    })
  });
  res.json({
    code: '0000',
    type:'multer',
    fileList:fileList
  });
});

在express中定义路由的回调函数时,把定义好了的upload对象作为中间件添加进去。如果是单个文件就用 single 方法,如果是多个文件就用 array 方法,这两个方法都需要传一个页面上定义好的字段名。

在路由的回调函数中,request对象已经有了file属性(单个文件上传)或files属性(多个文件上传),files属性是一个数组,数组的每一个对象都有以下属性:

  • fieldname:上传的字段名
  • originalname:上传的文件名
  • encoding:文件的编码类型
  • mimetype:文件的MIME类型
  • destination:存储的目录(和destination回调函数中的目录名一致)
  • filename:保存的文件名(和filename回调函数中的文件名一致)
  • path:保存的相对路径
  • size:文件的大小(单位:字节byte)

我们可以发现在路由的回调函数中的file对象比diskStorage中的file对象多了几个属性,这是因为在diskStorage中文件还没有保存,只能知道文件的大致属性;而路由的回调函数文件已经在服务器上保存好了,文件的保存路径以及文件的大小都是已知的。

过滤文件上传

在文件上传时,有时候会上传一些我们不需要的文件类型,我们需要把一些不需要的文件给过滤掉。demo2地址 。

文件类型过滤

var upload = multer({
  //...其他代码
  fileFilter: function(req, file, cb){
    if(file.mimetype == 'image/png'){
      cb(null, true)
    } else {
      cb(null, false)
    }
  }
});

在定义存储器的时候,新增一个fileFilter函数,用来过滤掉我们不需要的文件,在回调函数中我们传入true/false来代表是否要保存;如果传了false,那么destination函数和filename函数也不会调用了。

文件大小和数量过滤

var upload = multer({
  //...其他代码
  limits:{
    //限制文件大小10kb
    fileSize: 10*1000,
    //限制文件数量
    files: 5
  }
});

在定义存储器的时候,新增一个limits对象,用来控制上传的一些信息,它有以下一些属性:

  • fieldNameSize:field 名字最大长度,默认值:100 bytes
  • fieldSize:field 值的最大长度,默认值:1MB
  • fields:非文件 field 的最大数量
  • fileSize:在multipart表单中, 文件最大长度 (字节单位)
  • files:在multipart表单中, 文件最大数量
  • parts:在multipart表单中, part传输的最大数量(fields + files)

在这边我们把fileSize的值设置得小一点,设为10kb方便测试看效果,但是如果这个时候会发现有报错。因为上传的文件大小很容易就会超过10KB,导致有报错出现,我们就需要在路由回调里对错误的情况进行捕获。

//单个文件上传
let singleUpload = upload.single('singleFile');
app.post('/upload/single',(req,res)=>{
  singleUpload(req,res,(err)=>{
    if(!!err){
      console.log(err.message)
      res.json({
        code: '2000',
        type:'single',
        originalname: '',
        msg: err.message
      })
      return;
    }
    if(!!req.file){
      res.json({
        code: '0000',
        type:'single',
        originalname: req.file.originalname,
        msg: ''
      })
    } else {
      res.json({
        code: '1000',
        type:'single',
        originalname: '',
        msg: ''
      })
    }
  });
});

//多个文件上传
let multerUpload = upload.array('multerFile');
app.post('/upload/multer', (req,res)=>{
  multerUpload(req,res,(err)=>{
    if(!!err){
      res.json({
        code: '2000',
        type:'multer',
        fileList:[],
        msg: err.message
      });
    }
    let fileList = [];
    req.files.map((elem)=>{
      fileList.push({
        originalname: elem.originalname
      })
    });
    res.json({
      code: '0000',
      type:'multer',
      fileList:fileList,
      msg:''
    });
  });
});

所有的demo代码都在这个 仓库里

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
NodeJs读取JSON文件格式化时的注意事项
Sep 25 NodeJs
nodejs实例解析(输出hello world)
Jan 03 NodeJs
解析NodeJS异步I/O的实现
Apr 13 NodeJs
nodejs集成sqlite使用示例
Jun 05 NodeJs
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
Sep 06 NodeJs
详解IWinter 一个路由转控制器的 Nodejs 库
Nov 15 NodeJs
nodejs require js文件入口,在package.json中指定默认入口main方法
Oct 10 NodeJs
nodejs异步编程基础之回调函数用法分析
Dec 26 NodeJs
PHPStorm中如何对nodejs项目进行单元测试详解
Feb 28 NodeJs
nodejs中实现修改用户路由功能
May 24 NodeJs
nodejs和react实现即时通讯简易聊天室功能
Aug 21 NodeJs
nodejs中内置模块fs,path常见的用法说明
Nov 07 NodeJs
详解nodejs通过代理(proxy)发送http请求(request)
Sep 22 #NodeJs
使用vs code开发Nodejs程序的使用方法
Sep 21 #NodeJs
详解使用vscode+es6写nodejs服务端调试配置
Sep 21 #NodeJs
在Debian(Raspberry Pi)树莓派上安装NodeJS的教程详解
Sep 19 #NodeJs
Nodejs中使用phantom将html转为pdf或图片格式的方法
Sep 18 #NodeJs
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
Sep 18 #NodeJs
Nodejs+express+ejs简单使用实例代码
Sep 18 #NodeJs
You might like
PHILIPS L4X25T电路分析和打理
2021/03/02 无线电
ftp类(myftp.php)
2006/10/09 PHP
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
2007/04/18 PHP
PHP截取汉字乱码问题解决方法mb_substr函数的应用
2008/03/30 PHP
php笔记之:php函数range() round()和list()的使用说明
2013/04/26 PHP
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
兼容IE与firefox火狐的回车事件(js与jquery)
2010/10/20 Javascript
利用javascript判断文件是否存在
2013/12/31 Javascript
利用jQuery简单实现产品展示图片左右滚动功能(示例代码)
2014/01/02 Javascript
JavaScript实现动态添加,删除行的方法实例详解
2015/07/02 Javascript
jQuery unbind()方法实例详解
2016/01/19 Javascript
NodeJS连接MongoDB数据库时报错的快速解决方法
2016/05/13 NodeJs
JavaScript中对JSON对象的基本操作示例
2016/05/21 Javascript
JS实现旋转木马式图片轮播效果
2017/01/18 Javascript
Vue常用指令V-model用法
2017/03/08 Javascript
关于vue.js组件数据流的问题
2017/07/26 Javascript
浅谈关于angularJs中使用$.ajax的注意点
2017/08/12 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
在Vue组件中获取全局的点击事件方法
2018/09/06 Javascript
vue数据响应式原理知识点总结
2020/02/16 Javascript
Vue 中如何将函数作为 props 传递给组件的实现代码
2020/05/12 Javascript
详解三种方式在React中解决绑定this的作用域问题并传参
2020/08/18 Javascript
[01:42]TI4西雅图DOTA2前线报道 第一顿早饭哦
2014/07/08 DOTA
[40:17]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第一场
2018/04/06 DOTA
在Python中处理日期和时间的基本知识点整理汇总
2015/05/22 Python
Python闭包的两个注意事项(推荐)
2017/03/20 Python
浅谈django三种缓存模式的使用及注意点
2018/09/30 Python
[原创]Python入门教程3. 列表基本操作【定义、运算、常用函数】
2018/10/30 Python
matlab 计算灰度图像的一阶矩,二阶矩,三阶矩实例
2020/04/22 Python
AmazeUI 网格的实现示例
2020/08/13 HTML / CSS
写给爸爸的道歉信
2014/01/15 职场文书
授权委托书范本(单位)
2014/09/28 职场文书
幼儿园个人总结
2015/02/28 职场文书
文明上网主题班会
2015/08/14 职场文书
68句权威创业名言
2019/08/26 职场文书
PyTorch 如何检查模型梯度是否可导
2021/06/05 Python