文章原文:https://www.cnblogs.com/yalong/p/14766064.html
故事背景:
前端接口全部通過node層做的轉發,之前都是get post 等常見接口的轉發,后來來了一個下載的接口,node層轉發后,前端下載總是亂碼,文件打不開,經過各種查詢才解決,在此做個總結
先了解下,二進制文件流,從java后端,沒有經過node轉發,直接到前端頁面,然后下載到本地的整個流程
前端通過axios 請求下載接口,接口返回的其實是二進制文件,前端無法處理,可以把 axios 的 responseType 設置為blob, 這樣就可以直接拿到二進制文件轉化成的Blob, 然后對Blob處理下,就可以下載,具體代碼如下:
let result = await axios.request({
method: method,
url: url,
data: req.body,
responseType: 'blob'
});
// 這里是轉成 .xlsx 格式的文件
let blob = new Blob([result.data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
let blobHref = window.URL.createObjectURL(blob);
let anchor = document.createElement('a');
anchor.href = blobHref;
anchor.download = '文件名字';
document.body.appendChild(anchor);
anchor.click();
window.URL.revokeObjectURL(blobHref);
document.body.removeChild(anchor);
回到 我們在node層 轉發的問題,在node層其實也要用axios請求一次java后端的下接口,但是axios請求, 或者說 XMLHttpRequest 本身的 responseType, 默認是DOString, 在node層轉發的時候,我們想要的效果,是請求到二進制流,並把這個二進制流直接返給前端,這時候,就是對responseType進行設置了
如果不設置arraybuffer,前端拿到的就是二進制流轉成DOMString的結果了,就是個亂碼
responseType 的值
值 | 數據類型 |
---|---|
'' | DOMString (這個是默認類型) |
arraybuffer | ArrayBuffer對象 |
blob | Blob對象 |
document | Document對象 |
json | JavaScript object, parsed from a JSON string returned by the server |
text | DOMString |
在node端用axios請求的時候,需要把responseType 設置成 arraybuffer,arraybuffer 就 二進制數據緩沖區,可以用來保存二進制文件流
代碼如下:
router.all('/', async (ctx, next) => {
const req = ctx.request;
let url = req.url;
const method = req.method;
let result = await axios.request({
method: method,
url: url,
data: req.body,
responseType: 'arraybuffer'
});
下面這行不用加, koa2 會自動加上的
// ctx.set('Content-Type', 'application/octet-stream');
ctx.body = result.data;
});
這樣前端就可以按照跟請求java接口的方式,請求node層暴露出來的接口了。
參考鏈接: