Chrome中消失blob的神秘案例(在IndexedDB中)

时间:2014-10-27 03:33:07

标签: javascript google-chrome indexeddb

摘要

我想做的很简单:

  • 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上。如果不是,则从服务器(xhr.open)检索blob,将blob放入IndexedDB(objectStore.put)并显示blob(imgSrc = createTheObjectUrl(blob))。
  • 1b中。如果是,则从IndexedDB(objectStore.get)检索blob,从blob创建URL,将image src设置为URL。

问题是它最初有效,但过了一会儿(有时当我刷新页面时,有时当我关闭Chrome并返回网页时)我在访问网址时得到404(未找到)斑点。

有几点需要注意: -

  1. 在我对其他浏览器的有限测试中,我没有看到相同的行为 - 其他浏览器似乎工作正常。
  2. 当我查看blob-internals页面(chrome:// blob-internals)时,我的磁盘上有一个blob的路径。当它工作时(图像可见),该文件存在,当它开始失败时(404 Not Found)该文件不存在(即使blob-internals仍然引用它)。
  3. 当我尝试在jsfiddle中重现此问题时,问题不会发生。这是我的代码中的剪切和粘贴。不幸的是,我没有这个网络服务器的公开版本,因此我无法证明它失败了。
  4. 鉴于jsfiddle似乎总是有效,我所能想到的是我的服务器配置方式有所不同。我看一下返回的标题的区别,我可以看到在jsfiddle的情况下,启用了缓存。所以,我开始认为这与缓存有关(这可能是一个完全错误的假设)。就好像Chrome正在跟踪blob的使用情况并将其从文件系统中删除它一旦超出范围就会导致在没有文件的情况下在IndexedDB中输入(这本身就像一个bug)。我不想在服务器上启用缓存,或者blob的生命周期取决于服务器缓存设置。

    解决方法

    作为一种解决方法,我做了以下几点: -

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

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

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

1 个答案:

答案 0 :(得分:2)

好像是chrome中的一个bug 请参阅: https://code.google.com/p/chromium/issues/detail?id=108012#c162

铬金丝雀不会受其影响