Nodejs学习笔记web前端基础全栈之巅

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

2018-11-12  本文已影响7人  8b9a7eb5887b

一、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参考

属性:

方法:

对象:

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会将上传的文件暂存在内存中,而不会将其写入磁盘。

属性:

方法:

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 进行查看。

属性:

4.4 StorageEngine

multer.StorageEngine

构造:

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 应该接受或丢弃该文件。

参数:

示例:

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 对象可能尚未完全填充,这取决于客户端向服务器传输字段和文件的顺序。

属性:

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;
}

说明:

文件信息对象。

属性:

4.8 Instance

multer.Instance

构造:

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

方法:

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


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

上一篇下一篇

猜你喜欢

热点阅读