|
| 1 | +**此文档于2016年10月3日翻译时multer的版本是1.2.0,它可能不是最新的!** |
| 2 | +**甚至可能存在翻译错误!你可能需要阅读原版英语[README](../README.md)** |
| 3 | +**此文档仅供参考!** |
| 4 | + |
| 5 | +# Multer [](https://travis-ci.org/expressjs/multer) [](https://badge.fury.io/js/multer) [](https://github.com/feross/standard) |
| 6 | + |
| 7 | +Multer 是一个 node.js 中间件,用于处理 `multipart/form-data` 类型的表单数据, 它主要用于上传文件. 它是写在 [busboy](https://github.com/mscdex/busboy) 之上非常高效。 |
| 8 | + |
| 9 | +**注意**: Multer 不会处理任何非 `multipart/form-data` 类型的表单数据. |
| 10 | + |
| 11 | +## Language |
| 12 | +[English](../README.md) 简体中文 |
| 13 | + |
| 14 | +## 安装 |
| 15 | + |
| 16 | +```sh |
| 17 | +$ npm install --save multer |
| 18 | +``` |
| 19 | + |
| 20 | +## 使用 |
| 21 | + |
| 22 | +Multer 会添加一个 `body` 对象 以及 `file` 或 `files` 对象 到 `request` 对象中. |
| 23 | +`body` 对象包含表单的文本域信息, `file` 或 `files` 对象包含对象表单上传的文件信息. |
| 24 | + |
| 25 | +基本使用方法: |
| 26 | + |
| 27 | +```javascript |
| 28 | +var express = require('express') |
| 29 | +var multer = require('multer') |
| 30 | +var upload = multer({ dest: 'uploads/' }) |
| 31 | + |
| 32 | +var app = express() |
| 33 | + |
| 34 | +app.post('/profile', upload.single('avatar'), function (req, res, next) { |
| 35 | + // req.file 是 `avatar` 文件的信息 |
| 36 | + // req.body 将具有文本域数据, 如果存在的话 |
| 37 | +}) |
| 38 | + |
| 39 | +app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) { |
| 40 | + // req.files 是 `photos` 文件数组的信息 |
| 41 | + // req.body 将具有文本域数据, 如果存在的话 |
| 42 | +}) |
| 43 | + |
| 44 | +var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }]) |
| 45 | +app.post('/cool-profile', cpUpload, function (req, res, next) { |
| 46 | + // req.files 是一个对象 (String -> Array) 键是文件名, 值是文件数组 |
| 47 | + // |
| 48 | + // 例如: |
| 49 | + // req.files['avatar'][0] -> File |
| 50 | + // req.files['gallery'] -> Array |
| 51 | + // |
| 52 | + // req.body 将具有文本域数据, 如果存在的话 |
| 53 | +}) |
| 54 | +``` |
| 55 | + |
| 56 | +如果你需要处理一个只有文本域的表单, 你可以使用任何一个 multer 方法 (`.single()`, `.array()`, `fields()`). 下面是一个使用 `.array()`的例子: |
| 57 | + |
| 58 | +```javascript |
| 59 | +var express = require('express') |
| 60 | +var app = express() |
| 61 | +var multer = require('multer') |
| 62 | +var upload = multer() |
| 63 | + |
| 64 | +app.post('/profile', upload.array(), function (req, res, next) { |
| 65 | + // req.body 包含文本域 |
| 66 | +}) |
| 67 | +``` |
| 68 | + |
| 69 | +## API |
| 70 | + |
| 71 | +### 文件信息 |
| 72 | + |
| 73 | +每个文件具有下面的信息: |
| 74 | + |
| 75 | +Key | Description | Note |
| 76 | +--- | --- | --- |
| 77 | +`fieldname` | Field name 由表单指定 | |
| 78 | +`originalname` | 用户计算机上的文件的名称 | |
| 79 | +`encoding` | 文件编码 | |
| 80 | +`mimetype` | 文件的 Mime 类型 | |
| 81 | +`size` | 文件大小(字节单位) | |
| 82 | +`destination` | 保存路径 | `DiskStorage` |
| 83 | +`filename` | 保存在`destination`中的文件名 | `DiskStorage` |
| 84 | +`path` | 已上传文件的完整路径 | `DiskStorage` |
| 85 | +`buffer` | 一个存放了整个文件的 `Buffer` | `MemoryStorage` |
| 86 | + |
| 87 | +### `multer(opts)` |
| 88 | + |
| 89 | +Multer 接受一个 options 对象, 其中最基本的是 `dest` |
| 90 | +属性, 这将告诉 Multer 将上传文件保存在哪. 如果你省略 options 对象, 这些文件将保存在内存中,永远不会写入磁盘。 |
| 91 | + |
| 92 | +为了避免命名冲突, Multer 会修改上传的文件名. 这个重命名功能可以根据您的需要定制。 |
| 93 | + |
| 94 | +以下是可以传递给Multer的选项. |
| 95 | + |
| 96 | +Key | Description |
| 97 | +--- | --- |
| 98 | +`dest` or `storage` | 在哪里存储文件 |
| 99 | +`fileFilter` | 文件过滤器,控制哪些文件可以被接受 |
| 100 | +`limits` | 限制上传的数据 |
| 101 | + |
| 102 | +通常, 只需要设置 `dest` 属性 |
| 103 | +像这样: |
| 104 | + |
| 105 | +```javascript |
| 106 | +var upload = multer({ dest: 'uploads/' }) |
| 107 | +``` |
| 108 | + |
| 109 | +如果你想在上传时进行更多的控制, 你可以使用`storage`选项替代`dest`. Multer 具有 `DiskStorage` 和 `MemoryStorage` 两个存储引擎; 另外还可以从第三方获得更多可用的引擎. |
| 110 | + |
| 111 | +#### `.single(fieldname)` |
| 112 | + |
| 113 | +接受一个以 `fieldname` 命名的文件. 这个文件的信息保存在 `req.file`. |
| 114 | + |
| 115 | +#### `.array(fieldname[, maxCount])` |
| 116 | + |
| 117 | +接受一个以 `fieldname` 命名的文件数组. 可以配置 `maxCount` 来限制上传的最大数量. 这些文件的信息保存在 `req.files`. |
| 118 | + |
| 119 | +#### `.fields(fields)` |
| 120 | + |
| 121 | +接受指定 `fields` 的混合文件. 这些文件的信息保存在 `req.files`. |
| 122 | + |
| 123 | +`fields` 应该是一个对象数组,应该具有 `name` 和可选的 `maxCount`属性. |
| 124 | +Example: |
| 125 | + |
| 126 | +```javascript |
| 127 | +[ |
| 128 | + { name: 'avatar', maxCount: 1 }, |
| 129 | + { name: 'gallery', maxCount: 8 } |
| 130 | +] |
| 131 | +``` |
| 132 | + |
| 133 | +#### `.none()` |
| 134 | + |
| 135 | +只接受文本域. 如果任何文件上传到这个模式, 将发生 "LIMIT\_UNEXPECTED\_FILE" 错误. 这和 `upload.fields([])` 的效果一样. |
| 136 | + |
| 137 | +#### `.any()` |
| 138 | + |
| 139 | +接受一切. 文件数组将保存在 `req.files`. |
| 140 | + |
| 141 | +**警告:** 确保你总是处理了用户的文件上传. |
| 142 | +永远不要将multer作为全局中间件使用,因为恶意用户可以上传文件到一个你没有预料到的路由,应该只在你需要处理上传文件的路由上使用. |
| 143 | + |
| 144 | +### `storage` |
| 145 | + |
| 146 | +#### `DiskStorage` |
| 147 | + |
| 148 | +磁盘存储引擎可以让你控制文件的存储. |
| 149 | + |
| 150 | +```javascript |
| 151 | +var storage = multer.diskStorage({ |
| 152 | + destination: function (req, file, cb) { |
| 153 | + cb(null, '/tmp/my-uploads') |
| 154 | + }, |
| 155 | + filename: function (req, file, cb) { |
| 156 | + cb(null, file.fieldname + '-' + Date.now()) |
| 157 | + } |
| 158 | +}) |
| 159 | + |
| 160 | +var upload = multer({ storage: storage }) |
| 161 | +``` |
| 162 | + |
| 163 | +有两个选项可用, `destination` 和 `filename`. 他们都是用来确定文件存储位置的函数。 |
| 164 | + |
| 165 | +`destination` 是用来确定上传的文件应该存储在哪个文件夹中. 也可以提供一个 `string` (例如 `'/tmp/uploads'`). 如果没有设置 `destination` , 则使用操作默认的临时文件夹 |
| 166 | + |
| 167 | +**注意:** 如果你提供的 `destination` 是一个函数,你需要负责创建文件夹. 当提供一个字符串, multer 将确保这个文件夹是你创建的. |
| 168 | + |
| 169 | +`filename` 用于确定文件夹中的文件名的确定。 如果没有设置`filename` , 每个文件将设置为一个随机文件名,并且是没有扩展名的 |
| 170 | + |
| 171 | +**注意:** Multer 不会为你添加任何扩展名, 你的程序应该返回一个完整的文件名. |
| 172 | + |
| 173 | +每个函数都传递了两个请求(`req`) 和一些关于这个文件的信息 (`file`) 有助于你的决定。 |
| 174 | + |
| 175 | +注意 `req.body` 可能还没有完全填充.这取决于向客户端发送字段和文件到服务器的顺序。 |
| 176 | + |
| 177 | +#### `MemoryStorage` |
| 178 | + |
| 179 | +内存存储引擎将文件存储在内存中的 `Buffer` 对象. 它没有任何选项 |
| 180 | + |
| 181 | +```javascript |
| 182 | +var storage = multer.memoryStorage() |
| 183 | +var upload = multer({ storage: storage }) |
| 184 | +``` |
| 185 | + |
| 186 | +当使用内存存储引擎, 文件信息将包含一个 `buffer` 字段,里面包含了整个文件数据. |
| 187 | + |
| 188 | +**警告**: 当你使用内存存储,上传非常大的文件, 或者非常多的小文件, 会导致你的应用程序内存溢出 |
| 189 | + |
| 190 | +### `limits` |
| 191 | +一个对象,指定一些数据大小的限制。 Multer 通过这个对象使用 busboy , 详细的特性可以在 [busboy's page](https://github.com/mscdex/busboy#busboy-methods) 找到. |
| 192 | + |
| 193 | +可以使用下面这些: |
| 194 | + |
| 195 | +Key | Description | Default |
| 196 | +--- | --- | --- |
| 197 | +`fieldNameSize` | field 名字最大长度 | 100 bytes |
| 198 | +`fieldSize` | field 值的最大长度 | 1MB |
| 199 | +`fields` | 非文件 field 的最大数量 | 无限 |
| 200 | +`fileSize` | 在multipart表单中, 文件最大长度 (字节单位) | 无限 |
| 201 | +`files` | 在multipart表单中, 文件最大数量 | 无限 |
| 202 | +`parts` | 在multipart表单中, part传输的最大数量(fields + files) | 无限 |
| 203 | +`headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
| 204 | + |
| 205 | +设置 limits 可以帮助保护你的站点免受拒绝服务 (DoS) 攻击. |
| 206 | + |
| 207 | +### `fileFilter` |
| 208 | +设置一个函数来控制什么文件可以上传以及什么文件应该跳过,这个函数应该看起来像这样: |
| 209 | + |
| 210 | +```javascript |
| 211 | +function fileFilter (req, file, cb) { |
| 212 | + |
| 213 | + // 这个函数应该调用 `cb` 用boolean值来 |
| 214 | + // 指示是否应接受该文件 |
| 215 | + |
| 216 | + // 拒绝这个文件,使用`false`, 像这样: |
| 217 | + cb(null, false) |
| 218 | + |
| 219 | + // 接受这个文件,使用`true`, 像这样: |
| 220 | + cb(null, true) |
| 221 | + |
| 222 | + // 如果有问题,你可以总是这样发送一个错误: |
| 223 | + cb(new Error('I don\'t have a clue!')) |
| 224 | + |
| 225 | +} |
| 226 | +``` |
| 227 | + |
| 228 | +## 错误处理机制 |
| 229 | + |
| 230 | +当遇到一个错误, multer 将会把错误发送给 express. 你可以使用一个比较好的错误展示页 ([express标准方式](http://expressjs.com/guide/error-handling.html)). |
| 231 | + |
| 232 | +如果你想捕捉multer发出的错误, 你可以自己调用中间件程序. |
| 233 | + |
| 234 | +```javascript |
| 235 | +var upload = multer().single('avatar') |
| 236 | + |
| 237 | +app.post('/profile', function (req, res) { |
| 238 | + upload(req, res, function (err) { |
| 239 | + if (err) { |
| 240 | + // 发生错误 |
| 241 | + return |
| 242 | + } |
| 243 | + |
| 244 | + // 一切都好 |
| 245 | + }) |
| 246 | +}) |
| 247 | +``` |
| 248 | + |
| 249 | +## 定制存储引擎 |
| 250 | + |
| 251 | +如果你想要构建自己的存储引擎,请看 [这里](/StorageEngine.md) . |
| 252 | + |
| 253 | +## License |
| 254 | + |
| 255 | +[MIT](LICENSE) |
0 commit comments