What I am trying to do is pretty simple:
Somehow, between Blobs, objectURLs, indexedDB and caching it has all gotten overly complicated and is exhibiting some strange behaviour. If there was a way to stick an ArrayBuffer directly into an image rather than first converting to a Blob then an ObjectURL, then I would probably go with that as it is simpler and gets rid of the problematic Blobs and a few unnecessary steps.
If you would like to see a code sample of the flow then see this jsfiddle. Note that, as described below, the problem does not occur in the jsfiddle sample (for some reason that I can't figure out).
There is a reason that I am using IndexedDB rather than relying on browser caching, so lets try to avoid that discussion and has no bearing on the fact that IndexedDB seems to be misbehaving on Chrome.
I am interested if anyone else has encountered something similar or any suggestions as how to improve the situation.
Chrome version 38.0.2125.104 m.
Basically, the flow is to check if blob is in IndexedDB by index (see jsfiddle for reference):
xhr.open
), put the blob in IndexedDB (objectStore.put
) and show the blob (imgSrc = createTheObjectUrl(blob)
). objectStore.get
), create URL from blob, set image src to URL. The problem is that it works initially, but after a short while (sometimes when I refresh the page, sometimes when I close Chrome and return to the web page) I get a 404 (not found) when accessing the URL for the blob.
There are a few things to note: -
Given that jsfiddle always seems to work, all I can think is that there is something different about the way that my server is configured. I had a look at the difference in the headers being returned and I can see that in the case for jsfiddle, caching is enabled. So, I started thinking that this has something to do with caching (which could be a completely wrong assumption). It is as though Chrome is tracking the usage of the blob and deleting it from the file system as soon it goes out of scope which results in an entry in IndexedDB without a file (which in itself seems like a bug). I don't want to enable caching on the server or have the lifetime of the blob dependent on server cache settings.
As a workaround I did the following: -
This is not ideal as it means that I have an added overhead of reading the arraybuffer from the blob when first showing the image (before it is stored in IndexedDB) and then I have the overhead of reading the ArrayBuffer into a blob when retrieving from IndexedDB. Perhaps there is some clever shared resourcing going on which means that they use the same underlying buffer, but that means relying on the implementation for performance.
There is more - if I create a new Blob from the Blob that is returned by the server or create an ArrayBuffer from the Blob, then a new Blob from the ArrayBuffer it still does not work. It is as though there is some kind of shared reference counted resource being used. That is - any workaround I can think of that involves storing a blob in IndexedDB does not work.
Seems like a bug in chrome please see: https://code.google.com/p/chromium/issues/detail?id=108012#c162
chrome canary doesn't suffer from it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With