目前前后端下載方式通常分為兩種
第一種:
后端返回文件流,前端自己創建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