【问题标题】:The mysterious case of disappearing blobs in Chrome (in IndexedDB)Chrome 中 Blob 消失的神秘案例(在 IndexedDB 中)
【发布时间】:2014-11-14 17:26:14
【问题描述】:

总结

我想做的很简单:

  • 1a。如果图像不是某种类型的本地存储(例如 IndexedDB),则将图像作为字节数组从服务器读取,放入本地存储(作为字节数组或对文件的引用,我不在乎)
  • 1b。如果图像在本地存储中,则从本地存储中读取字节数组。将此字节数组显示为 html 页面中的图像。

不知何故,在 Blob、objectURL、indexedDB 和缓存之间,它都变得过于复杂,并且表现出一些奇怪的行为。如果有办法将 ArrayBuffer 直接粘贴到图像中,而不是先转换为 Blob,然后再转换为 ObjectURL,那么我可能会采用这种方法,因为它更简单,并且消除了有问题的 Blob 和一些不必要的步骤。

如果您想查看流程的代码示例,请查看此jsfiddle。请注意,如下所述,jsfiddle 示例中不会出现该问题(出于某种我无法弄清楚的原因)。

我使用 IndexedDB 而不是依赖浏览器缓存是有原因的,所以让我们尽量避免这种讨论,并且与 IndexedDB 似乎在 Chrome 上行为不端的事实无关。

如果其他人遇到过类似的事情或任何关于如何改善这种情况的建议,我很感兴趣。

详情

Chrome 版本 38.0.2125.104 m。

基本上,流程是通过索引检查blob是否在IndexedDB中(参考jsfiddle):

  • 1a。如果不是,则从服务器检索 blob (xhr.open),将 blob 放入 IndexedDB (objectStore.put) 并显示 blob (imgSrc = createTheObjectUrl(blob))。
  • 1b。如果是,则从 IndexedDB (objectStore.get) 中检索 blob,从 blob 创建 URL,将图像 src 设置为 URL。

问题是它最初可以工作,但不久之后(有时当我刷新页面时,有时当我关闭 Chrome 并返回网页时)我在访问 URL 时收到 404(未找到)斑点。

有几点需要注意:-

  1. 在我对其他浏览器的有限测试中,我没有看到相同的行为 - 其他浏览器似乎工作正常。
  2. 当我查看 blob-internals 页面 (chrome://blob-internals) 时,我的磁盘上有一个 blob 路径。当它工作时(图像可见),该文件存在,当它开始失败(404 Not Found)时,该文件不存在(即使 blob-internals 仍然引用它)。
  3. 当我试图在jsfiddle 中重现此问题时,问题并未发生。这是我的代码的剪切和粘贴。不幸的是,我没有这个网络服务器的公共版本,所以我不能证明它失败了。

鉴于 jsfiddle 似乎总是有效,我能想到的只是我的服务器配置方式有些不同。我查看了返回的标头的差异,我可以看到在 jsfiddle 的情况下,启用了缓存。所以,我开始认为这与缓存有关(这可能是一个完全错误的假设)。就好像 Chrome 正在跟踪 blob 的使用并在它超出范围时将其从文件系统中删除,这导致 IndexedDB 中的条目没有文件(这本身似乎是一个错误)。我不想在服务器上启用缓存或使 blob 的生命周期取决于服务器缓存设置。

解决方法

作为一种解决方法,我执行了以下操作:-

  • 1a。如果图像不在 IndexedDB 中,则将其作为 Blob 从服务器中检索。将 Blob 转换为 ArrayBuffer。作为 ArrayBuffer 存储在 IndexedDB 中。
  • 1b。如果图像在 IndexedDB 中,则检索,将 ArrayBuffer 转换为 Blob,从 Blob 创建 URL,将图像 src 设置为 URL。

这并不理想,因为这意味着我在第一次显示图像时(在它存储在 IndexedDB 中之前)从 blob 中读取数组缓冲区的开销增加了,然后在从 IndexedDB 中检索。也许有一些聪明的共享资源正在进行,这意味着它们使用相同的底层缓冲区,但这意味着依赖于实现来提高性能。

还有更多 - 如果我从服务器返回的 Blob 创建一个新的 Blob,或者从 Blob 创建一个 ArrayBuffer,然后从 ArrayBuffer 中创建一个新的 Blob,它仍然不起作用。就好像正在使用某种共享引用计数资源。也就是说 - 我能想到的任何涉及在 IndexedDB 中存储 blob 的解决方法都不起作用。

【问题讨论】:

  • Chrome 的一个很好的解决方法,在 iOS 中不起作用,所以我现在正在研究。
  • @ChristopherGrigg,感谢您的评论。我将移植到 iOS,所以我很想知道你发现了什么。

标签: javascript google-chrome indexeddb


【解决方案1】:

似乎是 chrome 中的错误 请参见: https://code.google.com/p/chromium/issues/detail?id=108012#c162

chrome canary 不受影响

【讨论】:

  • 谢谢我。如果 Chrome 更新后仍未修复,我将选择此作为已接受的答案并重新访问。
猜你喜欢
  • 2020-04-13
  • 2012-10-08
  • 2011-08-23
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 2012-12-02
相关资源
最近更新 更多