node服务器上传下载文件
node.js代码
公共代码
var express = require("express");
var formidable = require("formidable");//处理前端返回的formData
var fs = require("fs");//node自带的方法
var path = require("path");
var app = express();
var cors = require("cors"); //导入cors包
//设置跨域访问
var basePath = __dirname + "\\upload\\";配置上传的路径
app.use(cors()); //允许所有域名跨域
app.use(express.json());
var server = app.listen(3000, function () {
console.log("Example app listening at http://localhost:3000");
});
上传
app.post("/upload", async (req, res) => {
var form = new formidable.IncomingForm(); // 创建上传表单,前端代码上传时将要上传的文件转为FormData格式,
form.encoding = "utf-8"; // 避免中文乱码
form.uploadDir = basePath;//basePath为设置的上传路径
form.keepExtensions = true; // 保留后缀
form.maxFieldsSize = 2 * 1024 * 1024; // 文件大小(默认20M)
form.parse(req, function (err, fields, files) {
//files上传到路径;fields--文件传过来时formData append添加的其余文件属性,
if (err) {
res.send({
status: 201,
message: err,
});
return;
}
try {
// 若文件流的键名为uplaodFile,则filename = files.uplaodFile.name
var filename = files.file.originalFilename;
var filePath = fields.path;//传参的路径
var newPath = form.uploadDir + filePath + filename;//改成自己要存放的路径即可
var readStream = fs.createReadStream(files.file.filepath);//从该地址读取文件
var writeStream = fs.createWriteStream(newPath);
readStream.pipe(writeStream);//将读取的文件写入新地址
readStream.on("end", function () {
fs.unlinkSync(files.file.filepath);
});
res.send({ status: 200, message: "文件上传成功" });
} catch (err) {
res.send({
status: 201,
message: err,
});
return;
}
});
});
下载
app.get("/download", async (req, res) => {
var fileName = req.query.fileName;
// 创建可读流
try {
var rs = fs.createReadStream(__dirname + "/upload/files/" + fileName);//从存放路径读取要下载的文件
//const suffix = fileName.split(".").pop();
// 设置响应请求头,200表示成功的状态码,headers表示设置的请求头
res.writeHead(200, {
"Content-Type": "application/force-download;charset=UTF8",//UFT8支持中文
"Content-Disposition": `attachment; filename=${encodeURIComponent(
fileName
)}`,//这里设置下载的文件名
});
// 将可读流传给响应对象response
rs.pipe(res);
} catch (err) {
res.send({
status: 201,
message: err,
});
return;
}
});
前端代码
上传
//必须将文件封装未Formdata格式
beforeUpload(file) {
let formData = new FormData();
formData.append("file", file); //很重要 data.append("file", file);不成功
formData.append("title", file.name);
this.upload(formData);//上传接口
},
下载
先封装downlod接口
downlod.js文件
通过修改iframe的src来触发下载事件
// 一个全局的iframe用于下载,减少性能问题
const iframe = document.createElement("iframe");
setIframeStyle(iframe);
document.body.appendChild(iframe);
function setIframeStyle(iframe) {
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.style.margin = "0";
iframe.style.padding = "0";
iframe.style.overflow = "hidden";
iframe.style.border = "none";
iframe.style.display = "none";
iframe.style.visible = false;
}
const bindCallback = (iframe, onload) => {
// 绑定iframe的onload事件
if (
onload &&
Object.prototype.toString.call(onload) === "[object Function]"
) {
if (iframe.attachEvent) {
iframe.attachEvent("onload", onload);
} else if (iframe.addEventListener) {
iframe.addEventListener("load", onload);
} else {
iframe.onload = onload;
}
}
};
// { a: '11', b: 2, c: undefined }变为 ?a=11&b=2&c=
const toQueryParams = (params) => {
if (params !== {}) {
return (
"?" +
Object.keys(params)
.map((key) => {
// 这里如果参数值为false也应该传的
// if (params[key]) {
// return `${key}=${params[key].toString().replace(' ', '+')}`
// } else {
// return `${key}=`
// }
return `${key}=${params[key].toString().replace(" ", "+")}`;
})
.join("&")
);
}
return "";
};
// onload给iframe加载完成的回调
export default function (src, params, onload = () => {}) {
bindCallback(iframe, onload);
iframe.src = src + toQueryParams(params);
return iframe;
}
引入download方法
//API中的index文件
import _download from "../utils/download.js";
function downloadApi(url, params, callback) {
return _download(`${BASE_URL}/downLoad`, params, callback);
}
export {downloadApi}
参考文献:【1】https://www.jianshu.com/p/ad9f37ff6b50