在 Safari 中将 Blob 加载到 img 时出错(WebKitBlobResource 错误 1。)

use*_*510 8 safari blob canvas localforage createobjecturl

我正在尝试将一个 blob 保存到 localforage,然后检索它并显示它。它在一段时间内工作正常,但在几次页面刷新或浏览器关闭后,我在某些 blob 上收到错误。完整错误如下:

\n
Failed to load resource: The operation couldn\xe2\x80\x99t be completed. (WebKitBlobResource error 1.)\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的其余代码。将项目保存到 localforage:

\n
canvas.toBlob(function(blob){\n  allItems.push({"string":string,"blob":blob});\n  localforage.setItem("savedItems",allItems);\n},"image/jpeg",0.02);\n
Run Code Online (Sandbox Code Playgroud)\n

从 localforage 加载项目:

\n
localforage.getItem("savedItems").then(function(jsonData){\n  if(jsonData==null){allItems=[];}\n  else{allItems=jsonData;}\n});\n
Run Code Online (Sandbox Code Playgroud)\n

将 blob 添加到图像源:

\n
let thisURL = window.URL || window.webkitURL;\nlet url=thisURL.createObjectURL(allItems[k]['blob']);\nimg.src=url;\n
Run Code Online (Sandbox Code Playgroud)\n

这似乎是 Safari 特有的问题,因为我无法在 Chrome 中复制它。

\n

小智 4

更新 TLDR;

indexeddb 中的 Blob 在 iOS Webkit 中不可靠。因此,请将 blob 保存为数组缓冲区,并将 blob 的类型保存为 indexeddb 中的字符串。您可以获得 ArrayBuffer 和 blob 的类型,如下所示:

await blob.arrayBuffer()
blob.type
Run Code Online (Sandbox Code Playgroud)

当您想要从 indexeddb 检索数据并显示它时,只需从 ArrayBuffer 创建一个新的 blob 并输入:

const blob = new Blob([value.buffer], { type: value.type });
URL.createObjectURL(blob);
Run Code Online (Sandbox Code Playgroud)

调查

我在 iOS WebKit / safari 上有一个非常类似的问题:我还将从服务器接收到的图像和视频 blob 存储在 indexeddb 中。然后使用 createObjectUrl() 检索 Blob 并将其转换为 URL。这在除 WebKit / safari 之外的所有浏览器引擎上都能完美运行。iOS WebKit / safari 仅在前几次有效。我还没有找到完美的解决方案,但到目前为止我可以分享我的发现:

一般来说,对类似问题的所有评论都在说“WebKit 上的 blob 不可靠”。

有一些可能的解决方法:/sf/answers/4205286221/不过,我仍然必须尝试这个。

我们还可以做的是使用 fileReader 创建一个 base64 字符串并将其用作 src。而不是 createObjectUrl()。这可以这样实现:

const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result
};
Run Code Online (Sandbox Code Playgroud)

这不是一个理想的解决方案,因为我们现在有一些回调。

有一些提示指出必须正确指定 blob 的 mime 类型才能使其始终在 iOS WebKit / safari 中工作。

我将更深入地挖掘并在这里分享我的最终答案。也许其他人更快或者以前遇到过这个问题。