Zenn
Open5

WebKitBlobResourceエラー1

ムギュウムギュウ

SafariのindexedDBにBlob入れると、「エラー1」が出ることがある

「エラー1」だけでは原因を特定しにくいが、私の事例では以下の条件でエラーが発生した

  • indexedDBからBlobを読み込む
  • URL.createObjectURLで、BlobからobjectURLを生成する
  • indexedDBに再度同じBlobを書き込むと「エラー1」になる
ムギュウムギュウ

パフォーマンスの問題が生じた方法
indexedDBに直接Blob入れず、MIME typeとArrayBufferに分解してDBに入れる

DB読み込みが大幅に遅くなってしまった
画像を500枚くらいindexedDBに入れると、Android端末で全部読み込むまでに1分くらいかかってしまった

indexedDBのデータ構造を変えてマイグレーションする必要もあり、大掛かりになりやすい

ムギュウムギュウ

うまくいかなかった方法
blob.slice()structuredClone(blob)でBlobをcloneする

    const albumPutRequest = almapDB
      .transaction(["album"], "readwrite")
      .objectStore("album")
      .put({
        ...photo,
        blob: blob.slice(),
      });

結局「エラー1」が出るままだった
データ実体はcloneされず、あくまでBlob Objectがcloneされるらしい

ムギュウムギュウ

うまくいかなかった方法
BlobをcloneしてからindexedDBへ書き込む
FileReaderでデータ実体を読み直してcloneする

  // WebKitBlobResourceエラー1対策
  const clonedBlob = await new Promise<Blob>((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.onload = () => {
      if (!(fileReader.result instanceof ArrayBuffer)) {
        reject(new Error("Failed to read blob"));
        return;
      }

      resolve(new Blob([fileReader.result], { type: blob.type }));
    };
    fileReader.onerror = () => {
      reject(fileReader.error);
    };
    fileReader.readAsArrayBuffer(blob);
  });

どうもURL.revokeObjectURLするタイミング次第で、まだエラー1が出てしまうようだ

ログインするとコメントできます