XLSX 客户端从后端 api 响应中保存:二进制字符串、应用程序/八位字节流
Posted
技术标签:
【中文标题】XLSX 客户端从后端 api 响应中保存:二进制字符串、应用程序/八位字节流【英文标题】:XLSX client save from backend api response: binary string, application/octet-stream 【发布时间】:2018-12-19 21:00:43 【问题描述】:我需要将 XLSX 文件保存在我从 XHR 获取到 api 的前端。
在 api 响应中我得到了这个标题:
Content-Type: application/octet-stream
content-disposition: attachment; filename = OrdersList-253CREATED0.xlsx
以及响应正文的一部分:
PKõzMdocProps/core.xmlMKÄ0ïý!÷vVd-mQÅ++ÞB:¶Åæ$Úõßí®Å£ÇÉû¼Ã¤\ïåHÞѺA«²$¥Ðí º>6xE×uB[ÜZmÐú -å*Úo
'zÜ%!V!yÑVrFÛáâwYDÏ[î9l±Ytôè+ùwe+¥y³ã,hàwÀ߬G+Ý9YȽj¦dÊg.lÄàéîöa^>ó\ ¤uDHy²Â"÷Øà(üÁ~%»üêºÙÐ:KÙ*fYÌ.,-²¼8ËKøÕ?9£¶õe8Kd ...
在我的代码中,我尝试了很多选项:
1) 将 type: "application/octet-stream" 替换为 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
2) 创建没有 s2ab 函数的 blob/文件,例如 Blob([binary_string], ...)
let binary_string = response;
// Download using blob:
let ab = s2ab(binary_string),
blob = new Blob(
[ab],
type: "application/octet-stream"
);
let downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = 'test-blob.xlsx';
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
// Download using file
let FileSaver = require('file-saver'),
ab = s2ab(binary_string),
file = new File(
[ab],
"test-file.xlsx",
type: "application/octet-stream");
FileSaver.saveAs(file);
// s2ab function
function s2ab(s)
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
为什么我不能只使用 iframe 或 [下载]?因为需要授权标头。
响应中的文件是正确的,它在通过邮递员加载时打开,但是当我试图通过 XHR 响应中的 js 保存它时,它总是损坏。
非常感谢您的帮助:)
【问题讨论】:
您的 AJAX 代码丢失。 【参考方案1】:我解决了这个问题。 在这个项目中我使用了 react,所以我使用 axios 来处理 ajax 请求。
我认为问题出在某些 axios 设置或 axios 本身;
vanilla js 上的工作代码示例:
var request = new XMLHttpRequest();
request.open('GET', `http://localhost/api/get_xlsx`, true);
request.setRequestHeader('Token', 'user_auth_token_needed_in_my_app');
request.responseType = 'blob';
request.onload = function(e)
if (this.status === 200)
var blob = this.response;
if(window.navigator.msSaveOrOpenBlob)
window.navigator.msSaveBlob(blob, 'test.xlsx');
else
var downloadLink = window.document.createElement('a');
var contentTypeHeader = request.getResponseHeader("Content-Type");
downloadLink.href = window.URL.createObjectURL(new Blob([blob],
type: contentTypeHeader ));
downloadLink.download = 'test.xlsx';
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
;
request.send();
【讨论】:
以上是关于XLSX 客户端从后端 api 响应中保存:二进制字符串、应用程序/八位字节流的主要内容,如果未能解决你的问题,请参考以下文章