javascript - 通过 ajax 调用的大文件下载在 Chrome 浏览器中给出 "Network Error"

标签 javascript ajax google-chrome

所以我正在尝试下载一个 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/

相关文章:

javascript - 从 Javascript 访问 Chrome 的内部 gzip 例程

javascript - 混淆 .serialize() 和 .serializeElements()

javascript - 在窗口加载时创建显示隐藏功能?

带有嵌套对象字面量的 javascript 访问链

ajax - Node.js 和 Express;后404

javascript - 根据 MySQL 数据库值动态更改网站内容

java - 在测试中哪里使用ajax方法?如何查看我可以在哪里使用它们?

html - 如何在 Chrome 中禁用谷歌从 HTML 翻译

javascript - Chrome JS错误: Mixed Content: for roboto

javascript - 如何在覆盖警报功能后停止显示警报框