这篇文章主要介绍了Nodejs文件上传的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

笔者用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代码都在这个 仓库里

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持爱安网。

最新资讯
孙正义的出行帝国 下一个阿里巴巴在此

孙正义的出行帝国 下

马云背后的男人豪掷百亿美元砸向23家出行公司,要打造无
最后一位Siri联合创始人汤姆·格鲁伯已离开苹果

最后一位Siri联合创始

据外媒报道,苹果语音助手Siri联合创始人、人工智能专家
《王者荣耀》的电竞全球化困局

《王者荣耀》的电竞全

作为《王者荣耀》的海外版,AOV在多个国家由不同代理商
AI造梦到底是不是一笔好生意?

AI造梦到底是不是一笔

人类的梦境确实颇具神秘色彩,与梦境相关的影视作品也不
MCN选择综合症:短视频内容放谁家有钱赚?

MCN选择综合症:短视频

大量推陈出新的泛娱乐平台,让用户开始产生了“选择困难
阿里腾讯投资布局梳理:一级市场的钱会去哪里?

阿里腾讯投资布局梳理

国内风险投资市场经过20年的发展,已经从陪伴长跑型企业
最新文章
Angular2进阶之如何避免Dom误区

Angular2进阶之如何避

这篇文章主要介绍了Angular2进阶之如何避免Dom误区,小
使用FileReader API创建Vue文件阅读器组件

使用FileReader API创

这篇文章主要介绍了使用FileReader API创建一个Vue的
react 实现页面代码分割、按需加载的方法

react 实现页面代码分

本篇文章主要介绍了react 实现页面代码分割、按需加载
Vue项目分环境打包的实现步骤

Vue项目分环境打包的

这篇文章主要介绍了Vue项目如何分环境打包,实现方法大
vue 组件中slot插口的具体用法

vue 组件中slot插口的

这篇文章主要介绍了vue 中slot 的具体用法,包括子组件
JS遍历DOM文档树的方法实例详解

JS遍历DOM文档树的方

这篇文章主要介绍了JS遍历DOM文档树的方法,结合实例形