- javascript/
- Javascript 铬合金中消失斑点的神秘案例(IndexedDB)
总结
Javascript 铬合金中消失斑点的神秘案例(IndexedDB)
总结
Javascript 铬合金中消失斑点的神秘案例(IndexedDB)
总结,javascript,google-chrome,indexeddb,Javascript,Google Chrome,Indexeddb,我想做的很简单:
1a。如果映像不是某种类型的本地存储(如IndexedDB),则从服务器读取映像作为字节数组,放入本地存储(作为字节数组或文件引用,我不在乎)
1b。如果图像在本地存储中,请从本地存储中读取字节数组。在html页面中将此字节数组显示为图像
不知何故,在blob、objecturl、indexedDB和缓存之间,它变得过于复杂,并表现出一些奇怪的行为。如果有一种方法可以将ArrayBuffer直接粘贴到图像中,而不是先转换为Blob,然后再转换为ObjectURL,那么我可能
我想做的很简单:
- 1a。如果映像不是某种类型的本地存储(如IndexedDB),则从服务器读取映像作为字节数组,放入本地存储(作为字节数组或文件引用,我不在乎)
- 1b。如果图像在本地存储中,请从本地存储中读取字节数组。在html页面中将此字节数组显示为图像
不知何故,在blob、objecturl、indexedDB和缓存之间,它变得过于复杂,并表现出一些奇怪的行为。如果有一种方法可以将ArrayBuffer直接粘贴到图像中,而不是先转换为Blob,然后再转换为ObjectURL,那么我可能会使用这种方法,因为它更简单,并且可以消除有问题的Blob和一些不必要的步骤
如果您想查看流的代码示例,请查看此。请注意,正如下面所描述的,这个问题在jsfiddle示例中没有出现(出于某些我无法理解的原因)
我使用IndexedDB而不是依赖浏览器缓存是有原因的,所以让我们尽量避免这种讨论,并且与IndexedDB在Chrome上似乎行为不端这一事实无关
我很感兴趣的是,是否有其他人遇到过类似的问题或任何关于如何改善现状的建议
细节
Chrome版本38.0.2125.104 m
基本上,流程是按索引检查blob是否在IndexedDB中(请参阅以获取参考):
问题是它一开始是有效的,但过了一会儿(有时当我刷新页面时,有时当我关闭Chrome并返回网页时),当访问blob的URL时,我会得到404(未找到)
有几件事需要注意:-
在我对其他浏览器的有限测试中,我没有看到相同的行为——其他浏览器似乎工作正常
当我查看blob内部页面时(chrome://blob-internals)我的磁盘上有一个指向blob的路径。当它工作时(图像可见),该文件存在,当它开始失败时(404未找到),该文件不存在(即使blob内部仍然引用它)李>
当我试图在中重现这一点时,问题没有发生。这是我代码中的剪切粘贴。不幸的是,我没有这个web服务器的公共版本,所以我不能显示它失败了李>
考虑到JSFIDLE似乎总是可以工作,我所能想到的就是我的服务器配置方式有所不同。我查看了返回的头中的差异,可以看到在JSFIDLE的情况下,启用了缓存。所以,我开始认为这与缓存有关(这可能是一个完全错误的假设)。这就好像Chrome正在跟踪blob的使用情况,并在它超出范围时将其从文件系统中删除,从而导致IndexedDB中的条目没有文件(这本身似乎是一个bug)。我不希望在服务器上启用缓存,也不希望blob的生存期依赖于服务器缓存设置
变通办法
作为解决办法,我做了以下工作:-
- 1a。如果映像不在IndexedDB中,则将其作为Blob从服务器检索。将Blob转换为ArrayBuffer。作为ArrayBuffer存储在IndexedDB中李>
- 1b。如果图像位于IndexedDB中,则检索、将ArrayBuffer转换为Blob、从Blob创建URL、将图像src设置为URL李>
这并不理想,因为这意味着我在第一次显示图像时(在它存储到IndexedDB之前)会增加从blob读取arraybuffer的开销,然后在从IndexedDB检索时会增加将arraybuffer读入blob的开销。也许有一些聪明的共享资源正在进行,这意味着它们使用相同的底层缓冲区,但这意味着依赖于实现来获得性能
还有更多-如果我从服务器返回的Blob创建一个新Blob,或者从Blob创建一个ArrayBuffer,那么从ArrayBuffer创建一个新Blob仍然不起作用。这就好像使用了某种共享引用计数资源。也就是说,我能想到的任何涉及将blob存储在IndexedDB中的解决方案都不起作用 似乎是chrome中的一个bug
请参阅:
铬金丝雀不受它的影响谢谢你。我将选择此作为已接受的答案,并在更新Chrome时重新访问它,如果它仍然没有修复。Chrome的一个好的解决方案,在iOS中不起作用,因此我现在正在研究它。@ChristopherRigg,感谢您的评论。我将移植到iOS,所以我很想知道你发现了什么。