一、概念
Multer 是一個 node.js 中間件,用于處理 multipart/form-data 型別的表單資料,它主要用于上傳檔案,
注意: Multer 不會處理任何非 multipart/form-data 型別的表單資料,
二、安裝
npm i multer --save
三、使用(頁面底部有單檔案、多檔案上傳案例)
Multer 會在express 的 request 物件里添加一個 body 物件 (包含表單的文本域資訊)以及 file 或 files 物件 (單檔案通過req.file獲取,多檔案通過req.files獲取,file 或 files 物件包含物件表單上傳的檔案資訊),
四、基本使用
//1.引入依賴
const express = require('express')
const multer = require('multer')
//存盤在uploads檔案夾下面,沒有會直接創建
const upload = multer({ dest: 'uploads/' })
const app = express()
//相同的
//以下fielname(字串)必須前端傳過來的myformData物件的屬性名一致,不然后端接收不到這個檔案物件 // req.body 將具有文本域資料,如果存在的話
app.post('/profile', upload.single(fielname), function (req, res, next) {
//multer實體.single(fielname)——單檔案上傳,檔案物件獲取通過req.file
//multer實體.single(fieldame)——接受一個以fielname命名的檔案,這個檔案的資訊保存在req.file中的fielname屬性
// req.body 將具有文本域資料,如果存在的話
})
app.post('/photos/upload', upload.array(fielname, 12), function (req, res, next) {
//multer實體.array(fielname[,maxCount])——接收一個以fielname命名的檔案陣列;maxCount——限制上傳的最大數量,這些檔案的資訊保存在req.files里面
})
const cpUpload = upload.fields([{ name:fields[, maxCount: 1 ]}, { name: 'gallery', maxCount: 8 }])
//multer實體.files(fields)——接受指定fields的混合檔案,獲取——req.files
//fields應該是一個物件陣列,應該具有name和可選的maxCount屬性
app.post('/profile', upload.none(), function (req, res, next) {
//multer實體.none()——只接受文本域
})
五、檔案物件
后端接收到的檔案物件,檔案物件的接收見上一步
每個檔案具有下面的資訊
| Key | Description | Note |
|---|---|---|
fieldname | Field name 由表單指定(前后端一致) | |
originalname | 用戶計算機上的檔案的名稱 | |
encoding | 檔案編碼 | |
mimetype | 檔案的 MIME 型別 | |
size | 檔案大小(位元組單位) | |
destination | 保存路徑 | DiskStorage |
filename | 保存在 destination 中的檔案名 | DiskStorage |
path | 已上傳檔案的完整路徑 | DiskStorage |
buffer | 一個存放了整個檔案的 Buffer | MemoryStorage |
列印一下

六、配置引數options
Multer 接受一個 options 物件,其中最基本的是 dest 屬性(一般情況下使用dest就可以了),這將告訴 Multer 將上傳檔案保存在哪,如果你省略 options 物件,這些檔案將保存在記憶體中,永遠不會寫入磁盤,
為了避免命名沖突,Multer 會修改上傳的檔案名,這個重命名功能可以根據您的需要定制,
重命名可以通過new Date().getTime()拼接保證不重復,
如:file.filename.slice(0, 10) + new Date().getTime() + '.' + hou(hou——檔案后綴名的截取,也可以自己配置)
以下是可以傳遞給 Multer 的選項,
| Key | Description |
|---|---|
dest or storage | 在哪里存盤檔案 |
fileFilter | 檔案過濾器,控制哪些檔案可以被接受 |
limits | 限制上傳的資料 |
preservePath | 保存包含檔案名的完整檔案路徑 |
6.1storage存盤引擎
加強對檔案上傳的更多控制
6.1.1磁盤存盤引擎(DiskStorage)
磁盤存盤引擎可以讓你控制檔案的存盤
```javascript
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: storage })
有兩個選項可用,destination 和 filename,他們都是用來確定檔案存盤位置的函式,
destination 是用來確定上傳的檔案應該存盤在哪個檔案夾中,也可以提供一個 string (例如 '/tmp/uploads'),如果沒有設定 destination,則使用作業系統默認的臨時檔案夾,
注意: 如果你提供的 destination 是一個函式,你需要負責創建檔案夾,當提供一個字串,multer 將確保這個檔案夾是你創建的,
filename 用于確定檔案夾中的檔案名的確定, 如果沒有設定 filename,每個檔案將設定為一個隨機檔案名,并且是沒有擴展名的,
注意:Multer 不會為你添加任何擴展名,你的程式應該回傳一個完整的檔案名,
每個函式都傳遞了請求物件 (req) 和一些關于這個檔案的資訊 (file),有助于你的決定,
注意 req.body 可能還沒有完全 填充,這取決于向客戶端發送欄位和檔案到服務器的順序
6.1.2記憶體存盤引擎(MemoryStorage)
記憶體存盤引擎將檔案存盤在記憶體中的 Buffer 物件,它沒有任何選項,
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
當使用記憶體存盤引擎,檔案資訊將包含一個 buffer 欄位,里面包含了整個檔案資料,
警告: 當你使用記憶體存盤,上傳非常大的檔案,或者非常多的小檔案,會導致你的應用程式記憶體溢位,
6.2fileFiter(檔案過濾器)
設定一個函式來控制什么檔案可以上傳以及什么檔案應該跳過,這個函式應該看起來像這樣:
```javascript
function fileFilter (req, file, cb) {
// 這個函式應該呼叫 `cb` 用boolean值來
// 指示是否應接受該檔案
// 拒絕這個檔案,使用`false`,像這樣:
cb(null, false)
// 接受這個檔案,使用`true`,像這樣:
cb(null, true)
// 如果有問題,你可以總是這樣發送一個錯誤:
cb(new Error('I don\'t have a clue!'))
}
6.3limits(限制上傳的資料)
一個物件,指定一些資料大小的限制,
| Key | Description | Default |
|---|---|---|
fieldNameSize | field 名字最大長度 | 100 bytes |
fieldSize | field 值的最大長度 | 1MB |
fields | 非檔案 field 的最大數量 | 無限 |
fileSize | 在 multipart 表單中,檔案最大長度 (位元組單位) | 無限 |
files | 在 multipart 表單中,檔案最大數量 | 無限 |
parts | 在 multipart 表單中,part 傳輸的最大數量(fields + files) | 無限 |
headerPairs | 在 multipart 表單中,鍵值對最大組數 | 2000 |
七、錯誤處理機制
當遇到一個錯誤,multer 將會把錯誤發送給 express,
如果你想捕捉 multer 發出的錯誤,你可以自己呼叫中間件程式,如果你想捕捉multer錯誤,你可以使用 multer 物件下的 MulterError 類 (即 err instanceof multer.MulterError),
const multer = require('multer')
const upload = multer().single('avatar')
app.post('/profile', function (req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// 發生錯誤
} else if (err) {
// 發生錯誤
}
})
})
八、單檔案上傳案例
app.js基本配置
// 1.引入
const express = require('express')
const morgan = require('morgan')
const favicon = require('serve-favicon')
const path = require('path')
const router = require('./router/router')
// 2.創建服務器
const app = express()
//3.開放目錄
app.use(express.static(__dirname + '/public'))
// 開發日志
// app.use(morgan('dev'))
// 網頁圖示
app.use(favicon(path.join(__dirname, 'public', 'img', '1.jpg')))
// body請求(express4以上內置的)
app.use(express.urlencoded({ 'limit': '10mb', 'extended': true }))
app.use(express.json({ 'limit': '10mb' }))
app.use("/api", router)
// 監聽
app.listen(8000, (req, res) => {
console.log('服務已經運行\nhttp://127.0.0.1:8000\nhttp://localhost:8000');
})
router.js
// 1.引入
const express = require('express')
const multer = require('multer')
const path = require('path') //內置的路徑模塊
// 創建router
const router = express.Router()
// 設定保存路徑和檔案名
const storage = multer.diskStorage({
destination: function(req, res, cb) {
// 設定檔案存盤路徑
cb(null, './public/uploads')
},
filename: function(req, file, cb) {
// 設定檔案名
// Math.round(Math.random() *1E9)是生成一個整數部分9位數的亂數,再取整
let fileData = Date.now() + "-" + Math.round(Math.random() * 1e9) + path.extname(file.originalname);
cb(null, file.fieldname + "-" + fileData)
}
})
const upload = multer({
storage: storage
})
// 配置路由
router.post('/upload', upload.single('file'), (req, res) => {
console.log(req.file);
console.log(req.body);
// 隨便回應下
res.json({
code: 0,
msg: "ok"
})
})
// 匯出router
module.exports = router

前端
html
<body>
<form id="xcgg_yyds">
<input type="file" id="xcgg" accept=".png,.jpeg,.jpg,.gif">
</form>
</body>
js
$('#xcgg').on('change', function() {
console.log(this.files);
let fileObject = this.files[0]
let myFormData = new FormData()
myFormData.append('file', fileObject)
//隨便傳個看看
myFormData.append('name', 'xcgg')
$.ajax({
url: 'http://127.0.0.1:8000/api/upload',
type: 'post',
contentType: false,
processData: false,
data: myFormData,
success(res) {
console.log(res);
}
})
})
效果

九、多檔案上傳案列
html
<body>
<form id="xcgg_yyds">
<input type="file" id="xcgg" accept=".png,.jpeg,.jpg,.gif" multiple>
</form>
</body>
js
$('#xcgg').on('change', function() {
let fileObjects = this.files
let myFormData = new FormData()
myFormData.append('files', fileObjects)
//這里需要依次添加進去
for (let i = 0; i < fileObjects.length; i++) {
myFormData.append('files', fileObjects[i])
}
myFormData.append('name', 'xcgg')
$.ajax({
url: 'http://127.0.0.1:8000/api/upload',
type: 'post',
contentType: false,
processData: false,
data: myFormData,
success(res) {
console.log(res);
}
})
})
后端
攔截請求不同,其他都相同
router.post('/upload', upload.array('files', 3), function(req, res, next) {
let files = req.files //多檔案的獲取
console.log(req.files);
if (files.length === 0) {
res.json({
code: 500,
msg: '檔案上傳不能為空'
})
return
} else {
res.json({
code: 0,
msg: '上傳成功',
data: files
})
}
})
效果

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/382903.html
標籤:其他
