美文网首页Nodejs学习笔记web前端基础全栈之巅
Multer教程:基于Nodejs的文件上传

Multer教程:基于Nodejs的文件上传

作者: 8b9a7eb5887b | 来源:发表于2018-11-12 11:40 被阅读7次

    一、multer介绍

    multer是一个用来处理表单信息的nodejs中间件,主要是用于上传文件。multer基于busboy,拥有着更高的效率。

    使用multer,你需要为form表单加上字段属性:enctype="multipart/form-data",这是因为multer不会处理除了 multipart/form-data 形式的表单信息。

    二、安装multer

    npm install --save multer
    

    三、使用multer

    multer会在 request 对象身上增加了 body 对象和 file / files 对象。其中,body 对象包含了文本字段形式的请求参数,而 file / files 则是上传的文件。

    基本用法示例:

    <form action="/profile" method="post" enctype="multipart/form-data">   
      <input type="file" name="avatar" />
      <input type="text" name="nickname" />
    </form>
    
    const express = require('express');
    const multer = require('multer');
    
    const upload = multer({ dest: 'uploads/' });
    const app = express();
    
    app.post('/profile', upload.single('avatar'), (req, res, next) => {
      // req.file 就是你上传的名为 avatar 的文件对象
      // req.body 则包含文本字段形式的请求参数如 nickname
    });
    
    app.post('/profile', upload.array('avatar', 12), (req, res, next) => {
      // req.files 包含多个名为 avatar 的文件对象的数组
      // req.body 则包含文本字段形式的请求参数如 nickname
    });
    
    app.post('/profile', upload.fields([
      { name: 'avatar', maxCount: 1 },
      { name: 'gallery', maxCount: 8 }
    ]), (req, res, next) => {
      // res.files => {
      //   avatar: [], -> 包含多个名为 avatar 的文件对象的数组
      //   gallery: [] -> 包含多个名为 gallery 的文件对象的数组
      // }
      // req.body 则包含文本字段形式的请求参数如 nickname
    });
    

    如果你上传的表单中只包含文本字段形式的请求参数,不包含文件,则你可以使用 .none() 方法:

    app.post('/profile', upload.none(), (req, res, next) => {
       // req.body 则包含文本字段形式的请求参数如 nickname
    });
    

    四、API参考

    属性:

    • File

    方法:

    • multer
    • diskStorage
    • memoryStorage
    • fileFilter
    • destination
    • filename

    对象:

    • multerInstance
    • multerOptions
    • Limits
    • StorageEngine
    • DiskStorageOptions
    4.1 multer
    Multer multer(opts:Options);
    

    说明:

    创建 Instance 对象。

    返回值:

    Instance:instance对象。

    示例:

    const multer = require('multer');
    const upload = multer({ dest: 'uploads/' });
    
    4.2 Options

    multer.Options

    interface multerOptions {
      String dest;
      Limits limits;
      Boolean preservePath;
      StrorageEngine storage;
      function void fileFilter() {};
    }
    

    说明:

    用作 multer 方法的参数。一个最基本的 Options 应该含有一个 dest 字段,用于告诉 multer 你需要将上传的文件放置在哪一个文件夹下面。值得提醒的是,如果你忽略了这个属性,那么multer会将上传的文件暂存在内存中,而不会将其写入磁盘。

    属性:

    • limits:配置一些限制参数。
    • dest:将文件保存在哪个目录下。
    • storage:存储引擎,和 dest 一样的作用,两者配置一个即可,不同的地方将在下文提及。
    • preservePath:是否保留文件的完整路径,而不仅仅是基本名称。

    方法:

    • fileFilter:控制哪些文件需要上传以及哪些文件可以忽略。
    4.3 Limits

    multer.Options.Limits

    interface Limits {
      Number fieldNameSize;
      Number fieldSize;
      Number fields;
      Number fileSize;
      Number files;
      Number parts;
      Number headerPairs;
    }
    

    说明:

    配置了文件上传相关的一些大小限制。配置限制参数,有助于保护你的站点免受DoS攻击。multer 将这个对象直接传递给 busboy,更详细的属性可以前往 busboy 进行查看。

    属性:

    • fieldNameSize:字段名的最大长度,默认为 100 bytes。
    • fieldSize:字段值的最大长度,默认为 1 MB。
    • fields:非文件字段的最大数量,默认为 Infinity。
    • fileSize:对于多字段表单,最大的文件大小(单位:bytes),默认为 Infinity。
    • files:对于多字段表单,文件字段的最大数量,默认为 Infinity。
    • parts:对于多字段表单,全部字段的最大数量,默认为 Infinity。
    • headerPairs:对于多字段表单,解析的键值对最大数量,默认为 2000。
    4.4 StorageEngine

    multer.StorageEngine

    构造:

    • DiskStorage
    • MemoryStorage
    4.4.1 DiskStorage

    磁盘存储引擎

    StorageEngine multer.diskStorage(opts:DiskStorageOptions);
    

    说明:

    磁盘存储引擎为你提供了可以将文件保存到磁盘的完全控制权限。

    返回值:

    StorageEngine:存储引擎。

    示例:

    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads')
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })
     
    const upload = multer({ storage })
    
    4.4.2 MemoryStorage

    内存存储引擎

    StorageEnigine multer.memoryStorage();
    

    说明:

    内存存储引擎将文件作为缓存对象存储在内存中,它没有任何可配置的选项。使用内存存储引擎时,文件信息将包含一个名为 buffer 的字段,该字段包含了整个文件。需要提醒的是,当你使用内存存储引擎时,若上传非常大的文件或相对较小的大量文件时,将会导致应用程序内存不足。

    返回值:

    StorageEngine:存储引擎。

    4.5 fileFilter
    void fileFilter(
      req:Express.Request,
      file:Multer.File,
      callback:fileFilterCallback
    );
    

    说明:

    控制哪些文件可以上传,哪些文件选择忽略。在该函数内,你需要调用 callback 函数,并传入一个 Boolean 类型的参数,以告知 multer 应该接受或丢弃该文件。

    参数:

    • req:http请求对象
    • file:文件信息
    • callback:回调函数

    示例:

    const upload = multer({
      dest: 'uploads/',
      fileFilter: function (req, file, cb) {
        // 丢弃文件
        cb(null, false);
        // 接受文件
        cb(null, true);
        // 或者传递一个报错信息
        cb(new Error('报错信息'));
      }
    });
    
    4.6 DiskStorageOptions
    interface DiskStorageOptions {
      function void destination();
      function void filename();
    }
    

    说明:

    该对象拥有两个可配置的属性:destinationfilename 。这两个属性将决定文件应该被存储在哪里。每个函数被调用时,都将被传入一个 req 参数 和 一个 file 参数,以帮助你做出决策。需要提醒的是,此时 req 的 body 对象可能尚未完全填充,这取决于客户端向服务器传输字段和文件的顺序。

    属性:

    • destination:文件存储目录
    • filename:文件名
    4.6.1 destination
    void destination(
      req:Express.Request,
      file:Multer.File,
      callback:destinationCallback
    );
    

    说明:

    用于确定上传的文件应该被存储在哪个文件夹下。你需要调用 callback 函数,并传入一个 String 类型的参数,以告知 multer 应该将上传的文件存储在哪个文件夹下。特殊的:你也可以将该属性设置为 String 类型,它将直接表示文件夹的路径。如果你没有给出文件夹路径,那么上传的文件将会被存储在操作系统的临时文件默认目录。

    注意:当该属性为 Sting 类型时,multer 将确保为你创建目录;当该属性为 Function 时,则需要你事先创建好目录。

    示例:

    const storage = multer.diskStorage({
      destination: '/tmp/my-uploads'
    });
    
    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads');
      }
    });
    

    4.6.2 filename

    void filename(
      req:Express.Request,
      file:Multer.File,
      callback:filenameCallback
    );
    

    说明:

    用于确定文件夹中文件的名称,你需要调用 callback 函数,并传入一个 String 类型的参数,已告知 multer 将上传的文件命名为你需要的名称。如果你没有给出文件名,那么为了保证命名不重复,上传的每个文件,都将被命名为一个不包含文件扩展名的随机名称。

    注意:multer 不会为上传的文件自动添加文件扩展名,所以你传入的文件名参数中,一定要自己加上文件扩展名!

    示例:

    const storage = multer.diskStorage({
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now());
      }
    });
    
    4.7 File

    multer.File

    interface File {
      String fieldname;
      String originalname;
      String encoding;
      String mimetype;
      Number size;
      String destination;
      String filename;
      String path;
      Buffer buffer;
    }
    

    说明:

    文件信息对象。

    属性:

    • fieldname:表单中指定的字段名。
    • originalname:用户计算机上的文件名。
    • encoding:文件的编码类型。
    • mimetype:文件的mime类型。
    • size:文件大小。
    • destination:文件保存到的文件夹,使用DiskStorage时携带该属性。
    • filename:文件的名称,使用DiskStorage时携带该属性。
    • path:上传文件的完整路径,使用DiskStorage时携带该属性。
    • buffer:整个文件的缓存区,使用MemoryStorage时携带该属性。
    4.8 Instance

    multer.Instance

    构造:

    multer({ dest: 'uploads/' });
    

    方法:

    • single(fieldname):接受一个指定字段名的文件,文件信息将携带在 req 对象的 file 属性中。
    • array(fieldname[, maxCount]):接受一个指定字段名的文件数组,如果上传的文件数量超过 maxCount 则可能会报错。文件信息将以数组的形式携带在 reqfiles 属性中。
    • fields(fields):接受由字段指定的混合文件。具有文件数组的对象在存储在 req.files 中。
    • none():仅接受文本字段形式的请求参数。如果上传了文件,将发出代码为 LIMIT_UNEXPECTED_FILE 的错误。
    • any():接受所有通过游戏传送的文件。文件数组将存储在请求文件中。

    注意:切勿将 multer 添加文全局中间件,一些怀有恶意的用户可能会将文件上传到你没有预料到的路径。确保仅在处理上传文件的路由上使用此功能。


    以上便是有关 multer 的所有内容,希望对正在寻找这方面教程的你有所帮助。更详细的内容请前往 multer 查看。

    相关文章

      网友评论

        本文标题:Multer教程:基于Nodejs的文件上传

        本文链接:https://www.haomeiwen.com/subject/hedffqtx.html