? 作者簡(jiǎn)介:一名普通本科大三的學(xué)生,致力于提高前端開(kāi)發(fā)能力
? 個(gè)人主頁(yè):前端小白在前進(jìn)的主頁(yè)
?? 系列專(zhuān)欄 : node.js學(xué)習(xí)專(zhuān)欄
?? 個(gè)人社區(qū) : 個(gè)人交流社區(qū)
?? 學(xué)習(xí)格言: ?? 打不倒你的會(huì)使你更強(qiáng)!??
?? 刷題網(wǎng)站:這段時(shí)間有許多的小伙伴在問(wèn)有沒(méi)有什么好的刷題網(wǎng)站,博主在這里給大家推薦一款刷題網(wǎng)站:??點(diǎn)擊訪(fǎng)問(wèn)牛客網(wǎng)????途W(wǎng)支持多種編程語(yǔ)言的學(xué)習(xí),各大互聯(lián)網(wǎng)大廠(chǎng)面試真題,從基礎(chǔ)到拔高,快來(lái)體驗(yàn)一下吧!
??前言
在我們開(kāi)發(fā)中,如果想上傳文件,或者做個(gè)人中心的頭像的時(shí)候不會(huì)再向我們之前那樣僅僅發(fā)送一個(gè)post請(qǐng)求了,會(huì)指定相應(yīng)的配置,以及需要搭配一個(gè)中間件
Multer
,接下來(lái)將詳細(xì)展開(kāi)!
Multer中間件
Multer 是一個(gè) node.js 中間件,用于處理 multipart/form-data
類(lèi)型的表單數(shù)據(jù),它主要用于上傳文件。
注意: Multer 不會(huì)處理任何非 multipart/form-data 類(lèi)型的表單數(shù)據(jù)
。
文件上傳不同于我們傳給后端普通的鍵值對(duì),一般情況下我們所傳的類(lèi)型是x-www-form-urlencoded
,但是官方規(guī)定文件上傳
的類(lèi)型是multipart/form-data
,我們?nèi)绻约喝ヌ幚?code>multipart/form-data類(lèi)型的數(shù)據(jù)時(shí),非常的吃力,于是借助于Multer
中間件很好的解決了文件上傳的問(wèn)題。
安裝Multer
npm install --save multer
基本使用方法
const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const app = express()
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file 是 `avatar` 文件的信息
// req.body 將具有文本域數(shù)據(jù),如果存在的話(huà)
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files 是 `photos` 文件數(shù)組的信息
// req.body 將具有文本域數(shù)據(jù),如果存在的話(huà)
})
常用API解析
multer(opts)
Multer 接受一個(gè) options 對(duì)象
,其中最基本的是 dest 屬性
,這將告訴 Multer 將上傳文件保存在哪
。如果你省略
options 對(duì)象,這些文件將保存在內(nèi)存
中,永遠(yuǎn)不會(huì)寫(xiě)入磁盤(pán)
。
為了避免命名沖突,Multer 會(huì)修改上傳的文件名。這個(gè)重命名功能可以根據(jù)您的需要定制。
以下是可以傳遞給 Multer 的選項(xiàng):
鍵 | 描述 |
---|---|
dest or storage
|
在哪里存儲(chǔ)文件 |
fileFilter | 文件過(guò)濾器,控制哪些文件可以被接受 |
limits | 限制上傳的數(shù)據(jù) |
preservePath | 保存包含文件名的完整文件路徑 |
通常,一般的網(wǎng)頁(yè)應(yīng)用,只需要設(shè)置 dest
屬性,像這樣:
const upload = multer({ dest: 'uploads/' })
如果你想在上傳時(shí)進(jìn)行更多的控制,你可以使用 storage
選項(xiàng)替代 dest。Multer 具有 DiskStorage 和 MemoryStorage 兩個(gè)存儲(chǔ)引擎;另外還可以從第三方獲得更多可用的引擎。
.single(fieldname)
接受一個(gè)以 fieldname
命名的文件。這個(gè)文件的信息保存在 req.file
。
.array(fieldname[, maxCount])
接受一個(gè)以 fieldname
命名的文件數(shù)組
??梢耘渲?maxCount
來(lái)限制上傳的最大數(shù)量
。這些文件的信息保存在 req.files
。
storage
在這里就先給大家講述一個(gè)存儲(chǔ)引擎(磁盤(pán)存儲(chǔ)引擎 (DiskStorage)
),另外一個(gè)大家可以去github官網(wǎng)自行學(xué)習(xí),不要問(wèn)我為什么,因?yàn)樵谶@里只用了第一種(哈哈哈哈)
磁盤(pán)存儲(chǔ)引擎可以讓你控制文件的存儲(chǔ)
。
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 })
有兩個(gè)選項(xiàng)可用,destination
和 filename
。他們都是用來(lái)確定文件存儲(chǔ)位置的函數(shù)
。
destination
是用來(lái)確定上傳的文件應(yīng)該存儲(chǔ)在哪個(gè)文件夾中
。也可以提供一個(gè) string (例如 ‘/tmp/uploads’)。如果沒(méi)有設(shè)置 destination,則使用操作系統(tǒng)默認(rèn)的臨時(shí)文件夾
。
注意
: 如果你提供的 destination 是一個(gè)函數(shù)
,你需要負(fù)責(zé)創(chuàng)建文件夾
。當(dāng)提供一個(gè)字符串,multer 將確保這個(gè)文件夾是你創(chuàng)建的
。
filename 用于確定文件夾中的文件名的確定
。 如果沒(méi)有設(shè)置 filename,每個(gè)文件將設(shè)置為一個(gè)隨機(jī)文件名
,并且是沒(méi)有擴(kuò)展名
的。
注意
: Multer 不會(huì)為你添加任何擴(kuò)展名,你的程序應(yīng)該返回一個(gè)完整的文件名
。
每個(gè)函數(shù)都傳遞了請(qǐng)求對(duì)象 (req) 和一些關(guān)于這個(gè)文件的信息 (file),有助于你的決定。
注意
: req.body 可能還沒(méi)有完全填充,這取決于向客戶(hù)端發(fā)送字段和文件到服務(wù)器的順序。
警告
: 確保你總是處理了用戶(hù)的文件上傳。 永遠(yuǎn)不要將 multer 作為全局中間件使用
,因?yàn)閻阂庥脩?hù)可以上傳文件到一個(gè)你沒(méi)有預(yù)料到的路由,應(yīng)該只在你需要處理上傳文件的路由上使用。
這里是將官網(wǎng)中的話(huà)遷移了過(guò)來(lái)(Multer的官方解釋鏈接),因?yàn)槲矣X(jué)得官網(wǎng)講的已經(jīng)通俗易懂了,沒(méi)必要再去白話(huà)文化了,在這里已經(jīng)把我們要用的
multer
主要的部分講解了,接下來(lái)將進(jìn)行文件上傳功能
文件上傳功能實(shí)現(xiàn)
demo目錄架構(gòu)
入口文件(app.js)
const express = require('express')
const app = express()
const uploadRouter = require('./index')
//想要在前端頁(yè)面中訪(fǎng)問(wèn)到圖片,去掛載靜態(tài)資源
app.use(express.static('./public'))
//給路由掛載一個(gè)前綴
app.use('/api',uploadRouter)
app.listen(8080,()=>{
console.log('8080端口已啟動(dòng)...');
})
路由文件
const express = require('express')
//引入path模塊的目的在于獲取文件后綴名
const path = require('path')
const multer = require('multer')
const router = express.Router()
//進(jìn)行自定義儲(chǔ)存,并且將后端返回的文件加上后綴名后儲(chǔ)存到文件夾中
const storage = multer.diskStorage({
destination: function (req, file, cb) {
//在這里第二個(gè)參數(shù)傳遞了我們指定創(chuàng)建的儲(chǔ)存文件的文件夾
cb(null, 'public/uploads')
},
filename: function (req, file, cb) {
//path模塊獲取文件后綴
let ext = path.extname(file.originalname)
//根據(jù)時(shí)間戳生成文件名字
cb(null,Date.now() + ext)
}
})
//在這里告訴Multer文件保存到了指定位置
const upload = multer({ storage: storage })
router.post('/upload',upload.single('avater'),(req,res)=>{
console.log(req.file)
//將文件拼接成url地址,通過(guò)瀏覽器進(jìn)行訪(fǎng)問(wèn)文件
res.send({
msg: '圖片上傳成功',
url : `http://localhost:8080/uploads/${req.file.filename}`
})
})
module.exports = router
我們?cè)谶@里打印了req.file
,具體解析如下圖:
Postman測(cè)試
最終實(shí)現(xiàn)效果
補(bǔ)充
本篇文章中并沒(méi)有給大家結(jié)合html來(lái)給大家做一個(gè)前端的演示,但是實(shí)現(xiàn)的原理是一樣的,前端通過(guò)form表單或者FormData發(fā)送請(qǐng)求。
如果你是form表單直接提交,不要忘記在form添加屬性enctype="multipart/form-data"
,
如果你是通過(guò)FormData發(fā)送請(qǐng)求,不要忘記進(jìn)行一些配置(這里的代碼只是為了告訴你怎么去做,不要直接cv,要不然沒(méi)有效果
):文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-785608.html
const formdata = new FormData()
formdata.append('avater', avater.files[0])
const config = {
headers: {
"Content-Type":"multipart/form-data"
}
}
router.post('/api/upload', formdata, config).then(res => {
this.imgpath = 'http://localhost:8080' + res.data
})
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-785608.html
到了這里,關(guān)于【node進(jìn)階】Express+Multer+Postman模擬文件上傳功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!