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

1

10

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.

Agone answered 14/7, 2021 at 23:51 Comment(3)
Do you happen to use fragments on your blob URLs? I had problems with these specifically on iOS/WebKit. See w3.org/TR/media-frags about these. It's basically a hash at the end of the URL with some parameters.Deodar
I believe I was not using fragments. Are you seeing the error every time or just sporadically?Agone
With fragments, blobs fail every time for me. However, I also have instances without fragments that fail occasionally. With these, maybe it's also just that space is running out.Deodar
S
7

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://mcmap.net/q/1004067/-html5-video-source-as-locally-stored-blob-not-working-anymore 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.

Stake answered 6/12, 2021 at 23:29 Comment(1)
I have a simiular issue, I get that error only when I try to use createObjectURL on an image taken in landscape mode. Other case oy works idea?Airframe

© 2022 - 2024 — McMap. All rights reserved.