Nodejs實(shí)現(xiàn)文件上傳的示例代碼
筆者用nodejs做項(xiàng)目時需要用到文件上傳的功能,在網(wǎng)上搜索了很多教程,找到了一個express的中間件,用于處理 multipart/form-data 類型的表單數(shù)據(jù),可以很方便的將表單中的文件數(shù)據(jù)保存到服務(wù)器。
介紹
簡單的用法
定義存儲器
Multer作為express的一個中間件,我們可以很方便的自定義上傳的文件目錄以及保存的文件名。先看一個最簡單的用法, demo1地址 :
var express = require('express');
var multer = require('multer');
var app = express();
var upload = multer({
storage: multer.diskStorage({
destination: function (req, file, cb){
cb(null, './uploads/');
},
filename: function (req, file, cb){
//file.originalname上傳文件的原始文件名
var changedName = (new Date().getTime())+'-'+file.originalname;
cb(null, changedName);
}
})
});
我們先創(chuàng)建了一個upload對象,這個對象中destination函數(shù)用來定義上傳文件的存儲的文件夾;filename函數(shù)用來修改上傳文件存儲到服務(wù)器的文件名稱,這里我們我們加上一個時間戳簡單區(qū)分一下。這兩個函數(shù)都是通過回調(diào)函數(shù)來實(shí)現(xiàn)的。每次上傳的時候這兩個函數(shù)都會調(diào)用一次,如果是多個文件上傳,那個這兩個函數(shù)就調(diào)用多次,調(diào)用順序是先調(diào)用destination,然后調(diào)用filename。
在兩個函數(shù)中都會有一個 file 對象,表示當(dāng)前上傳的文件對象,有以下幾個屬性:
- fieldname:上傳的字段名
- originalname:上傳的文件名
- encoding:文件的編碼類型
- mimetype:文件的MIME類型
定義路由回調(diào)
//單個文件上傳
app.post('/upload/single',upload.single('singleFile'),(req,res)=>{
console.log(req.file);
res.json({
code: '0000',
type:'single',
originalname: req.file.originalname
})
});
//多個文件上傳
app.post('/upload/multer',upload.array('multerFile'),(req,res)=>{
console.log(req.files);
let fileList = [];
req.files.map((elem)=>{
fileList.push({
originalname: elem.originalname
})
});
res.json({
code: '0000',
type:'multer',
fileList:fileList
});
});
在express中定義路由的回調(diào)函數(shù)時,把定義好了的upload對象作為中間件添加進(jìn)去。如果是單個文件就用 single 方法,如果是多個文件就用 array 方法,這兩個方法都需要傳一個頁面上定義好的字段名。
在路由的回調(diào)函數(shù)中,request對象已經(jīng)有了file屬性(單個文件上傳)或files屬性(多個文件上傳),files屬性是一個數(shù)組,數(shù)組的每一個對象都有以下屬性:
- fieldname:上傳的字段名
- originalname:上傳的文件名
- encoding:文件的編碼類型
- mimetype:文件的MIME類型
- destination:存儲的目錄(和destination回調(diào)函數(shù)中的目錄名一致)
- filename:保存的文件名(和filename回調(diào)函數(shù)中的文件名一致)
- path:保存的相對路徑
- size:文件的大小(單位:字節(jié)byte)
我們可以發(fā)現(xiàn)在路由的回調(diào)函數(shù)中的file對象比diskStorage中的file對象多了幾個屬性,這是因?yàn)樵赿iskStorage中文件還沒有保存,只能知道文件的大致屬性;而路由的回調(diào)函數(shù)文件已經(jīng)在服務(wù)器上保存好了,文件的保存路徑以及文件的大小都是已知的。
過濾文件上傳
在文件上傳時,有時候會上傳一些我們不需要的文件類型,我們需要把一些不需要的文件給過濾掉。demo2地址 。
文件類型過濾
var upload = multer({
//...其他代碼
fileFilter: function(req, file, cb){
if(file.mimetype == 'image/png'){
cb(null, true)
} else {
cb(null, false)
}
}
});
在定義存儲器的時候,新增一個fileFilter函數(shù),用來過濾掉我們不需要的文件,在回調(diào)函數(shù)中我們傳入true/false來代表是否要保存;如果傳了false,那么destination函數(shù)和filename函數(shù)也不會調(diào)用了。
文件大小和數(shù)量過濾
var upload = multer({
//...其他代碼
limits:{
//限制文件大小10kb
fileSize: 10*1000,
//限制文件數(shù)量
files: 5
}
});
在定義存儲器的時候,新增一個limits對象,用來控制上傳的一些信息,它有以下一些屬性:
- fieldNameSize:field 名字最大長度,默認(rèn)值:100 bytes
- fieldSize:field 值的最大長度,默認(rèn)值:1MB
- fields:非文件 field 的最大數(shù)量
- fileSize:在multipart表單中, 文件最大長度 (字節(jié)單位)
- files:在multipart表單中, 文件最大數(shù)量
- parts:在multipart表單中, part傳輸?shù)淖畲髷?shù)量(fields + files)
在這邊我們把fileSize的值設(shè)置得小一點(diǎn),設(shè)為10kb方便測試看效果,但是如果這個時候會發(fā)現(xiàn)有報錯。因?yàn)樯蟼鞯奈募笮『苋菀拙蜁^10KB,導(dǎo)致有報錯出現(xiàn),我們就需要在路由回調(diào)里對錯誤的情況進(jìn)行捕獲。
//單個文件上傳
let singleUpload = upload.single('singleFile');
app.post('/upload/single',(req,res)=>{
singleUpload(req,res,(err)=>{
if(!!err){
console.log(err.message)
res.json({
code: '2000',
type:'single',
originalname: '',
msg: err.message
})
return;
}
if(!!req.file){
res.json({
code: '0000',
type:'single',
originalname: req.file.originalname,
msg: ''
})
} else {
res.json({
code: '1000',
type:'single',
originalname: '',
msg: ''
})
}
});
});
//多個文件上傳
let multerUpload = upload.array('multerFile');
app.post('/upload/multer', (req,res)=>{
multerUpload(req,res,(err)=>{
if(!!err){
res.json({
code: '2000',
type:'multer',
fileList:[],
msg: err.message
});
}
let fileList = [];
req.files.map((elem)=>{
fileList.push({
originalname: elem.originalname
})
});
res.json({
code: '0000',
type:'multer',
fileList:fileList,
msg:''
});
});
});
所有的demo代碼都在這個 倉庫里
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
npm報錯"A?complete?log?of?this?run?can?be?found?
這篇文章主要給大家介紹了關(guān)于npm報錯"A?complete?log?of?this?run?can?be?found?in:"的解決辦法,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-04-04
在Debian(Raspberry Pi)樹莓派上安裝NodeJS的教程詳解
在樹莓派上運(yùn)行NodeJS并不需要特別的配置,你只需要確保可以用openssh遠(yuǎn)程連接到你的樹莓派就ok了,關(guān)于在Debian(Raspberry Pi)樹莓派上安裝NodeJS的方法,大家可以通過本文了解下2017-09-09
如何刪除所有node_modules和package-lock配置文件
這篇文章主要介紹了如何刪除所有node_modules和package-lock配置文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
node.js中的events.emitter.once方法使用說明
這篇文章主要介紹了node.js中的events.emitter.once方法使用說明,本文介紹了events.emitter.once的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
node.js實(shí)現(xiàn)簡單的壓縮/解壓縮功能示例
這篇文章主要介紹了node.js實(shí)現(xiàn)簡單的壓縮/解壓縮功能,結(jié)合實(shí)例形式分析了node.js實(shí)現(xiàn)本地文件與服務(wù)器端壓縮/解壓縮相關(guān)操作技巧,需要的朋友可以參考下2019-11-11
詳解webpack打包nodejs項(xiàng)目(前端代碼)
這篇文章主要介紹了webpack打包nodejs項(xiàng)目(前端代碼),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09

