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());
});
