欢迎访问我的个人博客
项目地址
GitHub
码云
项目描述
- 使用 multer 中间件 来储存上传的文件
- 支持自定义保存到哪个文件目录下
文件上传功能的完整代码
后端
const express = require('express');
const app = express();
const bodyParser = require("body-parser");
const multer = require("multer");
const fs = require('fs');
const path = require('path');
app.all("/api/*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type, X-Requested-With, Authorization");
res.header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
res.header("X-Powered-By", "3.2.1");
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
app.use('*', (req, res, next) => {
res.setHeader('Cache-Control', 'max-age=10');
res.setHeader('Expires', new Date(Date.now() + 10).toUTCString());
next();
})
app.use(bodyParser.urlencoded({ limit: "20mb", extended: false }));
app.use(bodyParser.json({ limit: "20mb" }));
app.use("/resource", express.static(path.join(__dirname, "/resource")));
const storageFile = multer.diskStorage({
destination: function (req, file, cb) {
const folderName = (req.query.folderName || 'temp').trim();
const savePath = `./resource/${folderName}`;
const isExists = fs.existsSync(savePath);
if (!isExists) {
fs.mkdir(savePath, function (err) {
if (err) {
cb(null, `./resource/temp`);
} else {
cb(null, savePath);
}
})
} else {
cb(null, savePath);
}
},
filename: function (req, file, cb) {
const fileFormat = (file.originalname).split(".");
const newFileName = Date.now() + "." + fileFormat[fileFormat.length - 1];
cb(null, newFileName);
}
});
const fileUploadAPIUrl = "/api/uploadFile";
app.use(fileUploadAPIUrl, multer({ storage: storageFile }).array("file"));
app.post(fileUploadAPIUrl, (req, res) => {
const fileInfo = req.files[0];
if (!fileInfo) {
return res.json({
fail: true,
msg: "文件上传失败"
})
}
return res.json({
success: true,
msg: "文件上传成功",
data: {
originalName: Buffer.from(fileInfo.originalname, "latin1").toString(
"utf8"
),
fileSize: fileInfo.size,
filePath: '/' + fileInfo.path.replace(/\\/g, '/')
}
})
})
const port = 80;
app.listen(port, () => {
console.log(`服务已启动,端口号:${port}`);
})
前端
<!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>文件上传</title>
</head>
<body>
<input type="file" id="file" onchange="onUploadFile(this)" />
<p style="font-size: 11px; color: #f13;">
提示:选择完文件后,会立即上传到服务器
</p>
<script src="./axios.min.js"></script>
<script>
function onUploadFile(evt) {
const file = evt.files[0];
const fd = new FormData();
fd.append('file', file);
const folderName = "images";
const prefix = "http://127.0.0.1";
axios({
method: "POST",
url: `${prefix}/api/uploadFile?folderName=${folderName}`,
data: fd,
headers: {
"Content-Type": "multipart/form-data"
}
}).then(response => {
const res = response.data;
if (res.fail) {
return alert('文件上传失败')
}
const pEle = document.createElement('p');
const aEle = document.createElement('a');
const path = `${prefix}${res.data.filePath}`;
aEle.innerHTML = path;
aEle.setAttribute('target', '_blank');
aEle.setAttribute('href', path);
pEle.appendChild(aEle);
document.body.appendChild(pEle);
document.querySelector('#file').value = "";
}).catch(err => {
console.error(err);
});
}
</script>
</body>
</html>