目前前后端下载方式通常分为两种
第一种:
后端返回文件流,前端自己创建blob对象和A链接下载
第二种:
后端返回可写流,前端直接location.href或者A连接直接下载
第二种无疑对于前端同学更省事,无代码侵入和无感知下载
我今天用node express框架做代码演示 java等其他语言实现也大致相同
下面将两种下载方式的前后端代码分别展示:
第一种下载方式后端代码:
/** * 返回前端一个blob可写流,前端需要自己创建a连接下载 */ router.post('/downloadFile', async function (req, res, next) { res.setHeader('Content-type', 'application/octet-stream'); res.setHeader('Content-Disposition', 'attachment;filename=www.pdf'); // 'aaa.txt' can be customized. // var fileStream = fs.createReadStream('./www.pdf'); // fileStream.on('data', function (data) { // res.write(data, 'binary'); // }); // fileStream.on('end', function () { // res.end(); // console.log('The file has been downloaded successfully!'); // }); res.download('./www.pdf'); });
第一种下载方式前端代码:
downloadfromBlob(){ axios.post('/dev-api/provider-node/ship/downloadFile', {}, { responseType: 'blob' /**这里是response的content-type,开始架构师让改res的type, 我在上面的headers中加了content-type,改的是req的type*/ }).then((res) => { /*此方法为展示图片 start*/ let imgsrc = window.URL.createObjectURL(res.data) /*end*/ /*此方法为下载文件到本地 start*/ // let type = 'application/msword' // let type = 'application/octet-stream' // let type = result.type let type = 'application/pdf;chartset=UTF-8' // const buf = Buffer.from(result, 'binary') let blob = new Blob([res.data], {type: type}) let fileName = res.headers.filename || '未知文件' if (typeof window.navigator.msSaveBlob !== 'undefined') { /* * IE workaround for "HTML7007: One or more blob URLs were revoked by closing * the blob for which they were created. These URLs will no longer resolve as * the data backing the URL has been freed." */ window.navigator.msSaveBlob(blob, fileName); } else { let URL = window.URL || window.webkitURL let objectUrl = URL.createObjectURL(blob) console.log(objectUrl) if (fileName) { var a = document.createElement('a') // safari doesn't support this yet if (typeof a.download === 'undefined') { window.location = objectUrl } else { a.href = objectUrl a.download = fileName document.body.appendChild(a) a.click() a.remove(); console.log(`${fileName} 已下载`); } } else { window.location = objectUrl } /*end*/ } }).catch((err) => { console.log(err) message.error( '系统错误,请稍后重试'); }); },
第二种下载方式后端代码:
/** * 返回前端一个可写流,浏览器访问url自动下载 */ router.get('/downloadFileFromUrl', async function (req, res, next) { res.setHeader('Content-type', 'application/octet-stream'); res.setHeader('Content-Disposition', 'attachment;filename=www.pdf'); // 'aaa.txt' can be customized. res.setHeader('Transfer-Encoding','chunked'); // 'aaa.txt' can be customized. res.setHeader('Connection', 'keep-alive'); // 'aaa.txt' can be customized. var fileStream = fs.createReadStream('./www.pdf'); fileStream.on('data', function (data) { res.write(data, 'binary'); }); fileStream.on('end', function () { res.end("success"); console.log('The file has been downloaded successfully!'); }); // res.json({code:200,url:'http://127.0.0.1:8750/www.pdf'}) // res.download('upload/www.pdf','www.pdf'); });
第二种下载方式前端代码:
前端根据后端返回的url;直接访问后端返回url即可下载,也可使用location.href 获知window.open等方式直接下载
let url = `http://127.0.0.1:8750/ship/downloadFileFromUrl`;
//后端返回的下载连接
window.location.href = url