所以我正在尝试下载一个 zip 文件,其中包含对我的 api 的 ajax 调用。 api 以 base 64 编码字节数组响应。现在对于大多数下载来说,这工作得很好,但是当 zip 文件变得太大时,它在 Chrome 中开始失败。在所有其他浏览器中工作正常。根据我在堆栈溢出上的发现,这是 chrome 中的一个已知问题,人们建议使用 blob。事情是我正在使用 blob,但仍然有问题。这是我处理下载的代码。我使用它通过为 contentType 传递不同的值来下载 pdf 和 zip 文件。有没有人遇到过这个问题?是否有任何变通办法或脚本可以添加到页面来解决此问题?
// data is base 64 encoded byte array
function download(data, filename, contentType) {
var byteCharacters = atob(data);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob = new Blob([byteArray], { type: contentType });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// IE / edge workaround
window.navigator.msSaveOrOpenBlob(blob, filename);
} else if (navigator.userAgent.indexOf("Firefox") > 0) {
var a = window.document.createElement('a');
a.download = filename;
a.style.cssText = "display: none";
a.target = "_blank";
// Append anchor to body.
document.body.appendChild(a);
a.href = "data:" + contentType + ";base64," + data;
a.click();
// Remove anchor from body
document.body.removeChild(a);
} else //Chrome, safari, etc
{
var a = document.createElement("a");
a.style = "display: none";
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}
}
最佳答案
The api responds with a base 64 encoded byte array
为什么?我建议您添加一个方法来响应纯二进制 zip 文件。
设置 xhr.responseType = "blob";
并像在 Chrome 中一样保存它。
如果您想保持 api 不变,请尝试摆脱 Array 并直接填充 Uint8Array。
更新。我在 Ubuntu 18.04 下使用 16GB RAM 在我的 Chrome 69 上测试了这个,我发现 Chrome 不会让我以这种方式下载超过 1000 兆字节。
您尝试下载的文件有多大?
自己检查(不要忘记确保没有任何东西会阻止下载):
function getBlob(size) {
let u8a = new Uint8Array(size);
for (var i = 0; i < size; i++) {
u8a[i] = 33 + Math.floor(Math.random() * 5)
}
return new Blob([u8a]);
}
function downloadFile(source, filename) {
if (source instanceof (File, Blob)) {
filename = source.name || filename;
source = URL.createObjectURL(source);
}
let link = document.createElement("a");
link.style.display = "none";
link.href = source;
link.download = filename || "blob.bin";
document.body.appendChild(link);
link.click();
setTimeout(function () {
document.body.removeChild(link);
URL.revokeObjectURL(source);
}, 3000);
}
Size (MB): <input id="in" type=number min=1 max=3000>
<button onclick="downloadFile(getBlob(1024*1024*(+document.getElementById('in').value)))">download</button>
关于javascript - 通过 ajax 调用的大文件下载在 Chrome 浏览器中给出 "Network Error",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52538997/