我知道在SO上已经有很多与这种问题相关的问题,例如:
- 创建内存中的文件供用户下载,而不是通过服务器
- 使用HTML5 / JavaScript生成和保存文件
- Data协议URL大小限制
- 使用文件名保存JavaScript文件
- 在JavaScript中从base64字符串创建Blob
- 在“窗口”上执行'atob'失败
这个问题非常特定于iOS 8.1.3(Mobile,iPad 2+)上的Safari。我们有一个离线的AngularJS web应用程序,使用Application Cache和IndexedDB存储数据。一种数据是PDF文档,可以相对较大:最大约为25兆字节。我们将这些文件存储在IndexedDB中,当用户想要下载它时,我们使用JavaScript在浏览器中将这个文件保存在内存中。
问题实际上出现在用户想要保存它时。Safari移动版可能会因为Data URI的大小限制或其他原因而崩溃。
this.save = function (file) {
var mediaType = "application/pdf";
var link = document.createElement("a");
var blob = new Blob([this.fromBase64ToBinary(file.content)], { type: mediaType });
var blobUrl = URL.createObjectURL(blob);
document.body.appendChild(link);
link.download = file.name;
link.href = blobUrl;
link.click();
document.body.removeChild(link);
};
我们有一个服务,其中有一个函数save(file)
,其中file
是一个包含两个属性的对象:
name
:文件名;content
:文件数据,其为base64编码,然后我们将其转换为二进制。
atob()
函数可能会导致问题吗?当我在运行这段代码的iPad上逐步调试时,它就崩溃了(即:带有var byteCharacters = atob(b64Data);
行的位置)。
this.fromBase64ToBinary = function (base64) {
var byteCharacters = atob(base64);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
return new Uint8Array(byteNumbers);
};
atob
会导致程序崩溃。 - ykaragol