multer中間件,可以很方便的結合express處理用戶表單上傳的文件。
一、安裝multer
npm install multer
二、處理單個文件上傳
const express = require('express'); const multer = require('multer'); const path = require('path'); let app = express(); app.listen(8888); app.get('/', function (req, res) { res.sendFile(path.join(__dirname, 'index.html')); }); //創建一個multer對象,dest用來設置上傳文件存放的目錄 let upload = multer({dest: 'uploads/'}); //single()方法是用來處理單個文件上傳,注意參數的名字要與表單中的name值一致 app.post('/upload', upload.single('img'), function (req, res) { //body里面存放了表單的文本域信息 console.log(req.body); //file存放了單個文件的信息 console.log(req.file); res.end('ok'); });
index.html的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表單</title> </head> <body> <form action="http://localhost:8888/upload" method="post" enctype="multipart/form-data"> 用戶名:<input type="text" name="name"><br> 密碼:<input type="password" name="pwd"><br> 圖片:<input type="file" name="img"><br> <input type="submit" value="提交"> </form> </body> </html>
點擊提交后,可以看到在upload目錄下有一個文件生成了,這個文件就是我們上傳的文件,不過好像擴展名沒有了。
二、處理多個文件上傳
處理多個文件上傳,可以使用 array() 或 fields() 方法。
const express = require('express'); const multer = require('multer'); const path = require('path'); let app = express(); app.listen(8888); app.get('/', function (req, res) { res.sendFile(path.join(__dirname, 'index.html')); }); let upload = multer({dest: 'uploads/'}); //array()方法用於處理多個文件上傳 //參數一表示,文件上傳表單name屬性的值 //參數二表示,允許上傳文件個數 app.post('/uploads', upload.array('imgs', 3), function (req, res) { //files存放了多個文件的信息,是一個數組 console.log(req.files); res.end('ok'); }); //fields()方法也可以處理多個文件,參數是一個對象數組。 //對象中用name指定文件上傳表單name屬性的值,maxCount指定允許上傳文件個數 app.post('/objects', upload.fields([ {name: "head", maxCount: 1}, {name: "info", maxCount: 3} ]), function (req, res) { //files是一個對象,鍵就是我們上面設置的name的值,值就是文件數組 console.log(req.files); res.end('ok'); });
index.html的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表單</title> </head> <body> <form action="http://localhost:8888/uploads" method="post" enctype="multipart/form-data"> 用戶名:<input type="text" name="name"><br> 密碼:<input type="password" name="pwd"><br> 圖片1:<input type="file" name="imgs"><br> 圖片2:<input type="file" name="imgs"><br> 圖片3:<input type="file" name="imgs"><br> <input type="submit" value="提交"> </form> <form action="http://localhost:8888/objects" method="post" enctype="multipart/form-data"> 用戶名:<input type="text" name="name"><br> 密碼:<input type="password" name="pwd"><br> 頭像:<input type="file" name="head"><br> 信息1:<input type="file" name="info"><br> 信息2:<input type="file" name="info"><br> <input type="submit" value="提交"> </form> </body> </html>
三、自定義文件存儲路徑和文件名
上面的代碼我們通過配置 dest 來指定存放目錄。不過如果上傳文件過多,單一的存放在一個目錄下肯定有問題,所以需要我們自定義。
還有文件上傳后,都沒有擴展名了,這顯然也需要我們自定義。
const express = require('express'); const multer = require('multer'); const path = require('path'); const fs = require('fs'); let app = express(); app.listen(8888); app.get('/', function (req, res) { res.sendFile(path.join(__dirname, 'index.html')); }); let upload = multer({ storage: multer.diskStorage({ //設置文件存儲位置 destination: function (req, file, cb) { let date = new Date(); let year = date.getFullYear(); let month = (date.getMonth() + 1).toString().padStart(2, '0'); let day = date.getDate(); let dir = "./uploads/" + year + month + day; //判斷目錄是否存在,沒有則創建 if (!fs.existsSync(dir)) { fs.mkdirSync(dir, {recursive: true}); } //dir就是上傳文件存放的目錄 cb(null, dir); }, //設置文件名稱 filename: function (req, file, cb) { let fileName = file.fieldname + '-' + Date.now() + path.extname(file.originalname); //fileName就是上傳文件的文件名 cb(null, fileName); } }) }); app.post('/uploads', upload.array('imgs', 3), function (req, res) { console.log(req.files); res.end('ok'); });
四、過濾上傳文件
有些時候我們希望用戶上傳的只是圖片文件,其他文件不讓上傳。
const express = require('express'); const multer = require('multer'); const path = require('path'); const fs = require('fs'); let app = express(); app.listen(8888); app.get('/', function (req, res) { res.sendFile(path.join(__dirname, 'index.html')); }); let upload = multer({ //用於過濾文件的函數 fileFilter: function (req, file, cb) { let ext = path.extname(file.originalname); let extArr = ['.jpg', '.jpeg', '.gif', '.png']; if (!extArr.includes(ext)) { //拒絕這個文件 //cb(null, false); //當然我們還可以發送一個錯誤 cb(new Error('擴展名不正確')); } //接受這個文件 cb(null, true); } }); app.post('/uploads', upload.array('imgs', 3), function (req, res) { console.log(req.files); res.end('ok'); }); //捕獲錯誤 app.use(function (err, req, res, next) { res.send(err.toString()); });