XLSX 客户端从后端保存 api 响应:二进制字符串,application/octet-stream
XLSX client save from backend api response: binary string, application/octet-stream
我需要将 XLSX 文件保存在从 XHR 到 api 的前端。
在 api 回复中我得到了这个 headers:
Content-Type: application/octet-stream
content-disposition: attachment; filename = OrdersList-253CREATED0.xlsx
和部分响应body:
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) 替换类型:"application/octet-stream" 到 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
2) 创建 blob/file 没有像这样的 s2ab 函数 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 或 [下载]?因为需要授权header。
来自响应的文件是正确的,它在通过邮递员加载时打开,但是当我试图通过来自 XHR 响应的 js 保存它时它总是损坏。
非常感谢您的帮助:)
我解决了这个问题。
在这个项目中,我使用的是 React,所以我使用 axios 来处理 ajax 请求。
我认为问题出在某些 axios 设置或 axios 本身;
香草 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 文件保存在从 XHR 到 api 的前端。
在 api 回复中我得到了这个 headers:
Content-Type: application/octet-stream
content-disposition: attachment; filename = OrdersList-253CREATED0.xlsx
和部分响应body:
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) 替换类型:"application/octet-stream" 到 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
2) 创建 blob/file 没有像这样的 s2ab 函数 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 或 [下载]?因为需要授权header。
来自响应的文件是正确的,它在通过邮递员加载时打开,但是当我试图通过来自 XHR 响应的 js 保存它时它总是损坏。
非常感谢您的帮助:)
我解决了这个问题。 在这个项目中,我使用的是 React,所以我使用 axios 来处理 ajax 请求。
我认为问题出在某些 axios 设置或 axios 本身;
香草 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();