前端(Vue2.0):文件下载请求
download:async function(){
let filename = this.basic.download_url.split('\\');
filename = filename[1];
let post_data = {
path:this.basic.download_url,//文件路径
filename:filename,//文件存储在数据库中的名字(不含中文字符)
originalname:this.basic.originalname//文件原本的名字(可能含有中文字符)
}
console.log(post_data);
try{
const res = await axios.post('/api/file_download/download_single',post_data,{responseType: 'blob'});
if(res.status!==200) return this.$message.error("请求失败,请检查网络设置!");
console.log(res);
const { data, headers } = res
const fileName = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1')
// 此处当返回json文件时需要先对data进行JSON.stringify处理,其他类型文件不用做处理
//const blob = new Blob([JSON.stringify(data)], ...)
const blob = new Blob([data],{type: headers['content-type']})
let dom = document.createElement('a')
let url = window.URL.createObjectURL(blob)
dom.href = url
dom.download = decodeURI(fileName)
dom.style.display = 'none'
document.body.appendChild(dom)
dom.click()
dom.parentNode.removeChild(dom)
window.URL.revokeObjectURL(url)
}catch(e){
console.log(e);
this.$message.error("出错了!");
}
}
后端:
//下载文件
router.post('/download_single',(req, res, next)=>{
const filePath = req.body.path;
const fileName = req.body.filename;
const originalname = req.body.originalname;
// 控制台调试
console.log(fileName,filePath);
res.setHeader('status',200);
res.set({
'content-type': 'application/octet-stream',
'content-disposition': 'attachment;filename=' + encodeURI(originalname)
})
fs.createReadStream(filePath).pipe(res)
})
整体思路为:
(1)数据库中存储的文件名和文件路径均不包含中文字符,如:
文件名filename:1618279134460.pdf
文件路径path:uploads\1618279134460.pdf
(2)在请求下载一个文件时,同时向后端传递了文件的原文件名(originalname)
文件的原文件名originalname:GB 15532-2008计算机软件测试规范.pdf
(3)下载时使用originalname对欲下载的文件进行重命名
按理说,我的path里不存在任何中文字符,绝不应该出现乱码问题
经过我的查找,确认问题在于下载pdf文件时调用了IDM下载插件(Chrome版),点击下载按钮弹出下面弹框
点击确定后会再次给后端发一个请求
结论:凡是调用了IDM进行下载的文件类型,均会遇路径乱码问题。
求懂的大神帮忙想想办法,多谢多谢!