user1763510
user1763510

Reputation: 1260

Error loading Blob to img in Safari (WebKitBlobResource error 1.)

I am trying to save a blob to localforage and then retrieve it and display it. It works fine for a while, but after a couple of page refreshes or browser closes I get an error on some of the blobs. The complete error is as follows:

Failed to load resource: The operation couldn’t be completed. (WebKitBlobResource error 1.)

Here is the rest of my code. Save item to localforage:

canvas.toBlob(function(blob){
  allItems.push({"string":string,"blob":blob});
  localforage.setItem("savedItems",allItems);
},"image/jpeg",0.02);

Load item from localforage:

localforage.getItem("savedItems").then(function(jsonData){
  if(jsonData==null){allItems=[];}
  else{allItems=jsonData;}
});

Add blob to image source:

let thisURL = window.URL || window.webkitURL;
let url=thisURL.createObjectURL(allItems[k]['blob']);
img.src=url;

This seems to be a Safari specific problem, as I am not able to replicate it in Chrome.

Upvotes: 11

Views: 8889

Answers (1)

maxcodefaster
maxcodefaster

Reputation: 91

Update TLDR;

Blobs in indexeddb are unreliable in iOS Webkit. So instead save your blobs as array buffer and the type of the blob as a string in the indexeddb. You can get the ArrayBuffer and the type of a blob-like this:

await blob.arrayBuffer()
blob.type

When you want to retrieve the data from the indexeddb and display it just create a new blob from the ArrayBuffer and type:

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

Investigation

I have a very similar issue on iOS WebKit / safari: I also store images and video blobs received from the server in the indexeddb. The blobs are then retrieved and converted to an URL with createObjectUrl(). This works perfectly on all browser engines except WebKit / safari. iOS WebKit / safari only works the first couple of times. I have not found a perfect solution but I can share my findings so far:

Generally, all comments to similar issues are saying "blobs on WebKit are unreliable".

There are some possible workarounds: https://stackoverflow.com/a/60075517/13517617 I still have to try this one though.

Also what we may can do is use the fileReader to create a base64 String and use this as src. instead of createObjectUrl(). This can be achieved like this:

const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result
};

This is not an ideal solution as we now have some callbacks.

There are some hints pointing to that the mime type of the blobs have to be specified correctly to make it work in iOS WebKit / safari all the time.

I will dig deeper and share my final answer here. Maybe some else is faster or has encountered this issue before.

Upvotes: 7

Related Questions