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)文章
詳解node child_process模塊學(xué)習(xí)筆記
這篇文章主要介紹了詳解node child_process模塊學(xué)習(xí)筆記,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01Nodejs使用fs-extra模塊進(jìn)行目錄和文件操作用法示例
fs-extra模塊是基于fs?的文件操作相關(guān)工具庫,封裝了一些fs實(shí)現(xiàn)起來相對(duì)復(fù)雜的工具,下面這篇文章主要給大家介紹了關(guān)于Nodejs使用fs-extra模塊進(jìn)行目錄和文件操作用法的相關(guān)資料,需要的朋友可以參考下2024-06-06