Express使用multer實(shí)現(xiàn)文件上傳的示例代碼
環(huán)境搭建
首先,創(chuàng)建一個(gè)新的項(xiàng)目目錄,并初始化 package.json 文件:
mkdir express-multer-test cd express-multer-test npm init -y
安裝必要的包:
npm install express multer cors
express:一個(gè)簡(jiǎn)潔而靈活的Node.js Web應(yīng)用框架。multer:一個(gè)用于處理multipart/form-data類型表單數(shù)據(jù),特別適合于處理文件上傳的中間件。cors:提供跨域資源共享(CORS)的中間件。
單文件上傳
后端實(shí)現(xiàn)
在項(xiàng)目根目錄下創(chuàng)建 index.js 文件,并添加以下內(nèi)容:
const express = require('express')
const multer = require('multer')
const cors = require('cors')
const app = express()
// 使用 cors 中間件,允許所有來源的請(qǐng)求
app.use(cors())
// 配置 multer 中間件,設(shè)置文件存儲(chǔ)的目錄為 'uploads/'
const upload = multer({ dest: 'uploads/' })
// 使用 multer 中間件處理單個(gè)文件上傳
// 創(chuàng)建一個(gè) 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)
前端實(shí)現(xiàn)
新建一個(gè) index.html,并通過 npx http-server 運(yùn)行:
<!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 目錄,里面就保存著我們上傳的文件。
多文件上傳
后端實(shí)現(xiàn)
在 index.js 中添加一個(gè)新的路由來處理多文件上傳:

bbb 路由通過 array 方法來取上傳的文件,并且指定最大數(shù)量的限制。
上傳的文件通過 req.files 來取。
前端實(shí)現(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ù)接收到了多個(gè)文件:

錯(cuò)誤處理
在 express 里,約定有 4 個(gè)參數(shù)的中間件為錯(cuò)誤處理中間件:
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');
}
});
不同字段上傳
后端實(shí)現(xiàn)
如果需要處理多個(gè)字段上傳文件,可以使用 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)
}
)
前端實(shí)現(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ù)器打印的信息:

不固定字段上傳
后端實(shí)現(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)
})
前端實(shí)現(xiàn)
改下前端代碼,這次設(shè)置 aaa、bbb、ccc、ddd 4 個(gè) 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 個(gè)文件,可以看到服務(wù)端打印的消息:

只不過這時(shí)候不是 key、value 的形式了,需要自己遍歷數(shù)組來查找。
文件名和存儲(chǔ)目錄自定義
之前通過 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())
// 磁盤存儲(chǔ)
const storage = multer.diskStorage({
// 自定義目錄
destination: function (req, file, cb) {
try {
// 嘗試創(chuàng)建一個(gè)文件夾
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 對(duì)象沒變:

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

到此這篇關(guān)于Express使用multer實(shí)現(xiàn)文件上傳的示例代碼的文章就介紹到這了,更多相關(guān)Express multer文件上傳內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
npm 雙網(wǎng)切換的實(shí)現(xiàn)示例
本文主要介紹了npm 雙網(wǎng)切換的實(shí)現(xiàn)示例,實(shí)現(xiàn)快速切換npm源,特別適合內(nèi)外網(wǎng)切換場(chǎng)景,通過幾個(gè)簡(jiǎn)單命令,自動(dòng)切換源,無需手動(dòng)配置,同時(shí)提供了完整操作流程和使用技巧,幫助用戶輕松管理多個(gè)源2026-06-06
Node.js利用js-xlsx處理Excel文件的方法詳解
這篇文章主要給大家介紹了關(guān)于Node.js利用js-xlsx處理Excel文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-07-07
用node和express連接mysql實(shí)現(xiàn)登錄注冊(cè)的實(shí)現(xiàn)代碼
本篇文章主要介紹了用node和express連接mysql實(shí)現(xiàn)登錄注冊(cè)的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07
express項(xiàng)目文件目錄說明以及功能描述詳解
這篇文章主要給大家介紹了關(guān)于express項(xiàng)目文件目錄說明以及功能描述的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Node.js創(chuàng)建HTTP文件服務(wù)器的使用示例
我們的目的比較簡(jiǎn)單,使用Node.js創(chuàng)建一個(gè)HTTP協(xié)議的文件服務(wù)器,你可以使用瀏覽器或其它下載工具到文件服務(wù)器上下載文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Nodejs+angularjs結(jié)合multiparty實(shí)現(xiàn)多圖片上傳的示例代碼
這篇文章主要介紹了Nodejs+angularjs結(jié)合multiparty實(shí)現(xiàn)多圖片上傳的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
NodeJS 創(chuàng)建目錄和文件的方法實(shí)例分析
這篇文章主要介紹了NodeJS 創(chuàng)建目錄和文件的方法,涉及node.js中fs模塊mkdir、writeFile及目錄判斷existsSync等方法的功能與相關(guān)使用技巧,需要的朋友可以參考下2023-04-04

