Express使用multer實現(xiàn)文件上傳的示例代碼
環(huán)境搭建
首先,創(chuàng)建一個新的項目目錄,并初始化 package.json 文件:
mkdir express-multer-test cd express-multer-test npm init -y
安裝必要的包:
npm install express multer cors
express:一個簡潔而靈活的Node.js Web應(yīng)用框架。multer:一個用于處理multipart/form-data類型表單數(shù)據(jù),特別適合于處理文件上傳的中間件。cors:提供跨域資源共享(CORS)的中間件。
單文件上傳
后端實現(xiàn)
在項目根目錄下創(chuàng)建 index.js 文件,并添加以下內(nèi)容:
const express = require('express')
const multer = require('multer')
const cors = require('cors')
const app = express()
// 使用 cors 中間件,允許所有來源的請求
app.use(cors())
// 配置 multer 中間件,設(shè)置文件存儲的目錄為 'uploads/'
const upload = multer({ dest: 'uploads/' })
// 使用 multer 中間件處理單個文件上傳
// 創(chuàng)建一個 POST 路由,路徑為 '/aaa',文件字段名為 'aaa'
app.post('/aaa', upload.single('aaa'), function (req, res, next) {
console.log('req.file', req.file)
console.log('req.body', req.body)
})
app.listen(3333)
前端實現(xiàn)
新建一個 index.html,并通過 npx http-server 運行:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script>
</head>
<body>
<input id="fileInput" type="file" />
<script>
const fileInput = document.querySelector('#fileInput')
async function formData() {
const data = new FormData()
data.set('name', 'Yun')
data.set('age', 20)
data.set('aaa', fileInput.files[0])
const res = await axios.post('http://localhost:3333/aaa', data)
console.log(res)
}
fileInput.onchange = formData
</script>
</body>
</html>
通過 FormData + axios 上傳文件
準(zhǔn)備一張圖片:

瀏覽器選中文件上傳:

服務(wù)端打印的結(jié)果是:

fieldname 是前端上傳過來的字段名
origialname 是圖片的原始名稱。
其余非文件字段在 req.body。
并且服務(wù)端多了 uploads 目錄,里面就保存著我們上傳的文件。
多文件上傳
后端實現(xiàn)
在 index.js 中添加一個新的路由來處理多文件上傳:

bbb 路由通過 array 方法來取上傳的文件,并且指定最大數(shù)量的限制。
上傳的文件通過 req.files 來取。
前端實現(xiàn)
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script>
</head>
<body>
<!-- input 標(biāo)簽添加 multiple 屬性允許多選 -->
<input id="fileInput" type="file" multiple />
<script>
const fileInput = document.querySelector('#fileInput')
async function formData2() {
const data = new FormData()
data.set('name', 'Yun')
data.set('age', 20)
;[...fileInput.files].forEach(item => {
data.append('bbb', item)
})
const res = await axios.post('http://localhost:3333/bbb', data)
console.log(res)
}
fileInput.onchange = formData2
</script>
</body>
</html>
服務(wù)接收到了多個文件:

錯誤處理
在 express 里,約定有 4 個參數(shù)的中間件為錯誤處理中間件:
app.post('/bbb', upload.array('bbb', 2), (req, res, next) => {
// ...之前的代碼
}, (err, req, res, next) => {
if (err instanceof MulterError && err.code === 'LIMIT_UNEXPECTED_FILE') {
res.status(400).end('Too many files uploaded');
}
});
不同字段上傳
后端實現(xiàn)
如果需要處理多個字段上傳文件,可以使用 fields 方法:
app.post(
'/ccc',
upload.fields([
{ name: 'aaa', maxCount: 3 },
{ name: 'bbb', maxCount: 2 },
]),
function (req, res, next) {
console.log('req.files', req.files)
console.log('req.body', req.body)
}
)
前端實現(xiàn)
async function formData3() {
const data = new FormData()
data.set('name', 'Yun')
data.set('age', 20)
data.append('aaa', fileInput.files[0])
data.append('aaa', fileInput.files[1])
data.append('bbb', fileInput.files[2])
data.append('bbb', fileInput.files[3])
const res = await axios.post('http://localhost:3333/ccc', data)
console.log(res)
}
上傳后,服務(wù)器打印的信息:

不固定字段上傳
后端實現(xiàn)
如果沒有明確前端傳過來的哪些字段是 file ,可以使用 any 接收:
app.post('/ddd', upload.any(), function (req, res, next) {
console.log('req.files', req.files)
console.log('req.body', req.body)
})
前端實現(xiàn)
改下前端代碼,這次設(shè)置 aaa、bbb、ccc、ddd 4 個 file 字段:
async function formData4() {
const data = new FormData()
data.set('name', 'Yun')
data.set('age', 20)
data.set('aaa', fileInput.files[0])
data.set('bbb', fileInput.files[1])
data.set('ccc', fileInput.files[2])
data.set('ddd', fileInput.files[3])
const res = await axios.post('http://localhost:3333/ddd', data)
console.log(res)
}
再次上傳 4 個文件,可以看到服務(wù)端打印的消息:

只不過這時候不是 key、value 的形式了,需要自己遍歷數(shù)組來查找。
文件名和存儲目錄自定義
之前通過 dest 指定了保存的目錄:

現(xiàn)在重新指定:
const express = require('express')
const multer = require('multer')
const cors = require('cors')
const fs = require('fs')
const path = require('path')
const app = express()
app.use(cors())
// 磁盤存儲
const storage = multer.diskStorage({
// 自定義目錄
destination: function (req, file, cb) {
try {
// 嘗試創(chuàng)建一個文件夾
fs.mkdirSync(path.join(process.cwd(), 'my-uploads'))
} catch (e) {}
cb(null, path.join(process.cwd(), 'my-uploads'))
},
// 自定義文件名
filename: function (req, file, cb) {
const uniqueSuffix =
Date.now() + '-' + Math.round(Math.random() * 1e9) + '-' + file.originalname
// 設(shè)置文件名為字段名+唯一后綴
cb(null, file.fieldname + '-' + uniqueSuffix)
},
})
const upload = multer({ storage })
app.post('/ddd', upload.any(), function (req, res, next) {
console.log('req.files', req.files)
console.log('req.body', req.body)
})
app.listen(3333)
file 對象沒變:

瀏覽器再次上傳,就可以看到目錄和文件名都修改了:

到此這篇關(guān)于Express使用multer實現(xiàn)文件上傳的示例代碼的文章就介紹到這了,更多相關(guān)Express multer文件上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解node child_process模塊學(xué)習(xí)筆記
這篇文章主要介紹了詳解node child_process模塊學(xué)習(xí)筆記,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
Nodejs使用fs-extra模塊進(jìn)行目錄和文件操作用法示例
fs-extra模塊是基于fs?的文件操作相關(guān)工具庫,封裝了一些fs實現(xiàn)起來相對復(fù)雜的工具,下面這篇文章主要給大家介紹了關(guān)于Nodejs使用fs-extra模塊進(jìn)行目錄和文件操作用法的相關(guān)資料,需要的朋友可以參考下2024-06-06

