基于Express+multer實現(xiàn)文件上傳功能
1.涉及依賴包
- multer: 處理文件上傳的
- cors: 處理跨域的
2.http-server
一個簡單的http服務(wù)器,經(jīng)常用于本地測試和開發(fā)
安裝
// 全局安裝 sudo npm install http-server -g
使用
// 在當前目錄下建立http服務(wù)器,啟動后可以直接打開輸出內(nèi)容里的ip地址 http-server . // 指定ip和端口號http-server [path] [options] http-server -a 127.0.0.1 -p 9090
啟動后即可根據(jù)所啟動服務(wù)器的地址來訪問該服務(wù)下的資源,默認訪問inex.html文件
3. 單文件上傳
安裝依賴
npm install express multer cors
npm install express multer cors
const express = require('express'); const multer = require('multer'); const cors = require('cors'); const app = express(); app.use(cors()); const upload = multer({ dest: 'files' }); app.post( '/upload', upload.single('aaa'), function (req, res, next) { console.log(req.file, 'file'); console.log(req.body, 'body'); }, function (err, req, res, next) {} ); app.listen(3333);
app.use是使用cors中間件來處理跨域。
multer處理文件上傳,指定保存文件的目錄是files。
因為multer本身是一個函數(shù),所以不需要app.use。
upload.single是在處理單文件的時候使用single。
upload.single('aaa')是指接文件的參數(shù)名是aaa。
創(chuàng)建一個index.html
文件來作為文件入口
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <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', 'yangmy'); data.set('age', 20); data.set('file', fileInput.files[0]); const res = await axios.post('http://localhost:3333/upload', data); } fileInput.onchange = formData; </script> </body> </html>
然后使用http-server
在當前目錄下啟動一個http
服務(wù):
在當前目錄下運行index.js
文件:
node index.js
在瀏覽器中打開http-server
創(chuàng)建的服務(wù)地址,此時后默認打開index.html
文件:
選一張圖片上傳:
此時可以看到瀏覽器的請求參數(shù)以及服務(wù)端打印的日志:
瀏覽器:
服務(wù)端:
然后就可以看到我們代碼中就會多出一個files
的文件夾,里面存放的是剛上傳的問件:
4.多文件上傳
在index.js
中添加一個新的路由,用于處理多文件上傳:
const express = require('express'); const multer = require('multer'); const cors = require('cors'); const app = express(); app.use(cors()); const upload = multer({ dest: 'files' }); app.post( '/upload', upload.single('file'), function (req, res, next) { console.log(req.file, 'file'); console.log(req.body, 'body'); }, function (err, req, res, next) {} ); app.post( '/uploads', upload.array('filelist', 2), function (req, res, next) { console.log(req.files, 'file'); console.log(req.body, 'body'); }, function (err, req, res, next) {} ); app.listen(3333);
這里修改了index.js
文件,添加了/uploads
接口,用作處理多文件上傳。相比于單文件上傳,修改了以下:
upload.single('file')
改成了upload.array('filelist', 2)
,因為要上傳多文件,所以single
變成了array
,第二個數(shù)字參數(shù)是文件上傳的數(shù)量限制。
新建一個multis.html
用來當作多文件上傳的頁面,頁面內(nèi)容是:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script> </head> <body> as <input id="fileInput" type="file" multiple /> <script> const fileInput = document.querySelector('#fileInput'); async function formData2() { const data = new FormData(); data.set('name', 'yangmy'); data.set('age', 20); [...fileInput.files].forEach((item) => { data.append('filelist', item); }); const res = await axios.post('http://localhost:3333/uploads', data); console.log(res); } fileInput.onchange = formData2; </script> </body> </html>
重新運行項目:node index.js
:
打開服務(wù)頁面,路由中輸入multis.html
路由,然后上傳兩個圖片文件:
此時訪問的是多文件上傳頁面,接口參數(shù)中的filelist
包含兩個文件參數(shù),再看控制臺打印的日志:
如圖:req.files
打印出兩個文件的數(shù)據(jù)
如果我們上傳超過2個文件的數(shù)據(jù)呢?上傳超過規(guī)定的文件數(shù)量后,文件上傳會失敗,并不會上傳到我們的files
文件夾中。
在多文件上傳的接口代碼中加入一個錯誤處理的中間件:
此時可以在接口函數(shù)的第四個參數(shù)中拿到錯誤信息,把錯誤信息打印一下,展示如下:
我們可以通過這個報錯的code來處理返回結(jié)果,在index.js
的多文件上傳接口后加上如下代碼:
這樣再次試試上傳多個文件的情況:
此時便會根據(jù)錯誤處理的邏輯,當上傳文件數(shù)量過多時接口會400,且返回to many file
的提示
5.多個字段上傳文件且限制不同
在index.js
文件中添加一個新的接口uploadFileds
,作為上傳多個字段,且限制不同的接口,代碼如下:
app.post( '/uploadFileds', upload.fields([ { name: 'files1', maxCount: 2 }, { name: 'files2', maxCount: 3 }, ]), function (req, res, next) { console.log(req.files, 'file'); console.log(req.body, 'body'); }, function (err, req, res, next) { console.log(err, 'err'); if (err.code === 'LIMIT_UNEXPECTED_FILE') { res.status(400).end('to many files'); } } );
其中upload.fields
指定了每個字段的字段名以及該字段名接收文件的限制,然后接收到請求后同樣使用req.files來獲取文件信息。
然后新建multisFileds.html
文件,作為這個測試的頁面,代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="https://unpkg.com/axios@0.24.0/dist/axios.min.js"></script> </head> <body> <input id="fileInput" type="file" multiple /> <script> const fileInput = document.querySelector('#fileInput'); async function formData2() { const data = new FormData(); data.set('name', 'yangmy'); data.set('age', 20); data.append('files1', fileInput.files[0]); data.append('files1', fileInput.files[1]); data.append('files2', fileInput.files[2]); data.append('files2', fileInput.files[3]); data.append('files2', fileInput.files[4]); const res = await axios.post( 'http://localhost:3333/uploadFileds', data ); console.log(res); } fileInput.onchange = formData2; </script> </body> </html>
其中上傳的字段名和接口中定義的都必須對應(yīng)才可以。
訪問multisFileds.html
頁面,并上傳五張圖片文件
上傳成功后我們看到存放文件夾的文件確實多了五條數(shù)據(jù),且,控制臺也打印出這些文件的信息
6.不確定上傳文件的字段
不確定上傳文件的字段以及限制時,使用upload.any()
來接收文件。
再次在index.js
中新增一個接口:
app.post( '/uploadfileNoname', upload.any(), function (req, res, next) { console.log(req.files, 'file'); console.log(req.body, 'body'); }, function (err, req, res, next) { console.log(err, 'err'); if (err.code === 'LIMIT_UNEXPECTED_FILE') { res.status(400).end('to many files'); } } );
復(fù)用multisFileds.html
文件,將上傳的接口改為uploadfileNoname
重新運行express應(yīng)用,然后在瀏覽器中打開multisFileds.html
頁面,選中文件上傳
上傳成功后看到files文件夾下面又多了5條文件數(shù)據(jù)
這時控制臺日志打印的文件內(nèi)容包含有所上傳的文件信息,但是這次沒有字段名,字段名都在文件信息中,需要一個個去遍歷處理
7.保存上傳的文件名
const upload = multer({ dest: 'files' });
之前通過dest指定了保存文件的路徑是files文件夾,現(xiàn)在修改一下,通過multer.diskStorage()
方法來配置filename
、destination
參數(shù),使其將文件保存在指定的文件夾,且指定文件名和文件名后綴 在index.js
中添加如下代碼:
const fs = require('fs'); const path = require('path'); const storage = multer.diskStorage({ // 目錄 destination: (req, file, cb) => { try { fs.mkdirSync(path.join(process.cwd(), 'uploadFile')); } catch (e) {} cb(null, path.join(process.cwd(), 'uploadFile')); }, // 文件名 filename: (req, file, cb) => { cb(null, file.originalname); }, }); const upload = multer({ storage });
要注意destination
和filename
中的回調(diào)函數(shù)cb
的第一個參數(shù)是傳的錯誤信息,所以這里要注意傳null。
生成的storage
要放到const upload = multer({ storage });
中,這樣上傳時就會走寫的那個方法了。
然后我們在上一個例子中使用上傳功能,成功上傳圖片后,發(fā)現(xiàn)上傳的圖片出現(xiàn)在了定義的uploadFile
文件夾下,且名字我們使用的是上傳文件原本的名稱
以上就是基于Express+multer來實現(xiàn)文件上傳功能的詳細內(nèi)容,更多關(guān)于Express multer文件上傳功能的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于node實現(xiàn)websocket協(xié)議
這篇文章主要介紹了基于node實現(xiàn)websocket協(xié)議的相關(guān)資料,需要的朋友可以參考下2016-04-04淺談如何通過node.js對數(shù)據(jù)進行MD5加密
本篇文章將主要針對于在NODE.JS中如何對數(shù)據(jù)進行MD5加密,MD5是一種常用的哈希算法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05express搭建的nodejs項目使用webpack進行壓縮打包
對于打包這個問題它并不是難點,但是對于我們這種初學(xué)者來說,根本就不知道應(yīng)該怎么做,下面這篇文章主要給大家介紹了關(guān)于express搭建的nodejs項目使用webpack進行壓縮打包的相關(guān)資料,需要的朋友可以參考下2022-12-12提升node.js中使用redis的性能遇到的問題及解決方法
本文中提到的node redis client采用的基于node-redis封裝的二方包,因此問題排查也基于node-redis這個模塊。接下來通過本文給大家分享提升node.js中使用redis的性能2018-10-10