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 Express4.x开发框架随手笔记
Nov 23 NodeJs
NodeJS使用formidable实现文件上传
Oct 27 NodeJs
Nodejs 搭建简单的Web服务器详解及实例
Nov 30 NodeJs
详解NodeJs支付宝移动支付签名及验签
Jan 06 NodeJs
Nodejs高扩展性的模板引擎 functmpl简介
Feb 13 NodeJs
nodejs mysql 实现分页的方法
Jun 06 NodeJs
使用nodeJs来安装less及编译less文件为css文件的方法
Nov 20 NodeJs
nodejs基于mssql模块连接sqlserver数据库的简单封装操作示例
Jan 05 NodeJs
nodejs实现的连接MySQL数据库功能示例
Jan 25 NodeJs
nodejs微信扫码支付功能实现
Feb 17 NodeJs
nodejs初始化init的示例代码
Oct 10 NodeJs
详解nodejs 开发企业微信第三方应用入门教程
Mar 12 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
PHP中file_exists()判断中文文件名无效的解决方法
2014/11/12 PHP
PHP加密解密类实例分析
2015/04/20 PHP
PHP浮点数精度问题汇总
2015/05/13 PHP
thinkphp框架类库扩展操作示例
2019/11/26 PHP
javascript replace()正则替换实现代码
2010/02/26 Javascript
读jQuery之九 一些瑕疵说明
2011/06/21 Javascript
给ListBox添加双击事件示例代码
2013/12/02 Javascript
JQuery boxy插件在IE中边角图片不显示问题的解决
2015/05/20 Javascript
JavaScript禁止用户多次提交的两种方法
2016/07/24 Javascript
移动端使用localStorage缓存Js和css文的方法(web开发)
2016/09/20 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
JavaScript利用fetch实现异步请求的方法实例
2017/07/26 Javascript
基于BootStrap multiselect.js实现的下拉框联动效果
2017/07/28 Javascript
基于node.js之调试器详解
2017/08/22 Javascript
使用canvas实现一个vue弹幕组件功能
2018/11/30 Javascript
vue实现将一个数组内的相同数据进行合并
2019/11/07 Javascript
Vue学习之常用指令实例详解
2020/01/06 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
[49:08]OpTic vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python itertools模块详解
2015/05/09 Python
Python写的一个定时重跑获取数据库数据
2016/12/28 Python
Python实现基于PIL和tesseract的验证码识别功能示例
2018/07/11 Python
python科学计算之scipy——optimize用法
2019/11/25 Python
jupyter notebook 恢复误删单元格或者历史代码的实现
2020/04/17 Python
Python如何读写CSV文件
2020/08/13 Python
matplotlib 使用 plt.savefig() 输出图片去除旁边的空白区域
2021/01/05 Python
卡塔尔航空官方网站:Qatar Airways
2017/02/08 全球购物
英国快时尚女装购物网站:PrettyLittleThing
2018/08/15 全球购物
linux比较文件内容的命令是什么
2015/09/23 面试题
市场营销工作计划书
2014/05/06 职场文书
团干部培训方案
2014/06/03 职场文书
《角的初步认识》教学反思
2016/02/17 职场文书
考生诚信考试承诺书(2016版)
2016/03/25 职场文书
Angular CLI发布路径的配置项浅析
2021/03/29 Javascript
Python使用海龟绘图实现贪吃蛇游戏
2021/06/18 Python
实现GO语言对数组切片去重
2022/04/20 Golang