下载
router.get("/download2", (req, res) => {
const fileName = encodeURIComponent("课程.png");
res.set({
"Content-Type": "application/octet-stream",
"Content-Disposition": `attachment; filename=${fileName}`,
});
res.sendFile(path.resolve(__dirname, "imgs/avatar.png"));
// res.download("./imgs/avatar.png");
});
以这种方式加fileName,需要注意axios的返回值,需要 res.headers.get("Content-disposition");
下载用sendFile或者download都可以,但自定义给文件命名download方法不行 前端接收时传{ responseType: 'blob'} 下载中就不用写 new Blob([res]) 传其他的比如 responseType: 'arraybuffer',就需要在前端写 new Blob,暂时不知道为什么 还有注意: responseType这个配置参数在get请求中可以不传参数,post不行
分片上传 前后端
前端
// 第一种切片
const fileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// console.log("file", e.target.files![0]);
const file = e.target.files![0];
const chunks = chunkFun(file);
uploadFile(chunks);
};
const chunkFun = (file, size = 1024 * 1024) => {
const chunks = [];
for (let i = 0; i < file.size; i += size) {
chunks.push(file.slice(i, i + size));
}
return chunks;
};
const uploadFile = (chunks) => {
const List = [];
for (let i = 0; i < chunks.length; i++) {
const formData = new FormData();
formData.append("index", i);
formData.append("total", chunks.length);
formData.append("fileName", "xiezhen");
formData.append("file", chunks[i]);
List.push(sliceUpload(formData));
}
Promise.all(List).then((res) => {
uploadMerge({ fileName: "myName" }).then((res) => {
console.log("merge done", res);
});
});
};
// 第二种切片
const fileChange2 = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files![0];
const { name, size } = file;
const chunkSlice = 1024 * 500;
let start = 0;
let index = 0;
while (start < size) {
let _blob;
if (start + chunkSlice > size) {
_blob = file.slice(start, size);
} else {
_blob = file.slice(start, start + chunkSlice);
}
const _file = new File([_blob], `${name}`);
const _formData = new FormData();
_formData.append("index", index + "");
_formData.append("fileName", "chunkwenjianming");
_formData.append("file", _file);
await sliceUpload(_formData);
start += chunkSlice;
index++;
}
// 这是接口
uploadMerge({ fileName: "视频" }).then((res) => {
console.log("merge done", res);
});
};
后端
// 切片上传
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads/");
},
filename: (req, file, cb) => {
cb(null, `${req.body.index}-${req.body.fileName}`);
},
});
const upload = multer({ storage });
// 分片上传
router.post("/up", upload.single("file"), (req, res) => {
res.send("ok");
});
//合并
router.post("/slice-merge", async (req, res) => {
const uploadPath = "./uploads";
let files = fs.readdirSync(path.join(process.cwd(), uploadPath));
files = files.sort((a, b) => a.split("-")[0] - b.split("-")[0]);
const writePath = path.join(
process.cwd(),
`video`,
`${req.body.fileName}.mp4`
);
files.forEach((item) => {
fs.appendFileSync(
writePath,
fs.readFileSync(path.join(process.cwd(), uploadPath, item))
);
fs.unlinkSync(path.join(process.cwd(), uploadPath, item));
});
res.send("ok 合并完了");
});