service-worker - 如何在获取事件期间将响应存储在索引数据库中

标签 service-worker indexeddb

因此,在获取事件期间,我必须捕获所有数据并将其存储在索引数据库中。如果我尝试下面的代码,我会收到如下错误:

DOMException:无法在“IDBObjectStore”上执行“put”:无法克隆响应对象。

我想达到什么目标?

  1. 将我的所有回复存储在索引数据库中
  2. 能够从中获取数据,以防我从索引数据库离线
  3. 如果我的数据库中没有数据,则回退到 html 页面。
self.addEventListener("fetch", (event) => {
  event.respondWith(
    new Promise((resolve,reject) => {
      if (navigator.onLine) {
        return fetch(event.request).then((response) => {
           dbRequest = indexedDB.open("CacheDB", 1);
          dbRequest.onupgradeneeded = function (e) {
            const db = e.target.result;
            if (!db.objectStoreNames.contains("CacheStore")) {
              db.createObjectStore("CacheStore");
            }
          };
          dbRequest.onsuccess = function (e) {
            const db = e.target.result;
            const tx = db.transaction("CacheStore", "readwrite");
            const store = tx.objectStore("CacheStore");
            console.log(response,event);
            try
            {
              const request = store.put(**response.clone()**`enter code here`);
              console.log("I am here")
              request.onsuccess = function (e) {
                console.log("Successfully cached!!");
                resolve(response);
              };
              request.onerror = function (e) {
                console.log("Error occures while storing =>", e);
              };
            }
            catch(err)
            {
              console.log("err =>",err);
              resolve(response);
            }
          
          };

          dbRequest.onerror = function (e) {
            console.log("Error occured while creating DB =>", e);
          };
          console.log("sending response");
          
        });
      } else {
        const dbRequest = indexedDB.open("CacheDB", 1);
        dbRequest.onsuccess = function (e) {
          const db = e.target.result;
          const tx = db.transaction("CacheStore", "readwrite");
          const store = tx.objectStore("CacheStore");
          const request = store.get(event.request.url);
          request.onsuccess = function (e) {
            console.log("db cahce.. =>", e);
            return request.result[0];
          };
          request.onerror = function (e) {
            console.log("Error occures while getting =>", e);
          };
        };
      }
    })
  );
});

最佳答案

当对象存储在索引数据库中时,它们会被序列化,这基本上是过去所谓的“结构化克隆”算法的前半部分,如下所述:https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data

该错误告诉您无法克隆(序列化/反序列化)Response对象 - 您也可以使用以下代码得到该错误:

window.postMessage(new Response)

...这意味着Response对象不支持序列化。要在 IndexedDB 中使用 postMessage() 或存储 Response,您需要将要序列化的属性提取到可序列化的对象中。例如一个普通的 JS 对象,将 header 和响应正文保存为 Blob

关于service-worker - 如何在获取事件期间将响应存储在索引数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70669589/

相关文章:

html - window.mozIndexedDB 在 Firefox 15 中为空

database - 从 HTML5 中的数据库中删除记录

javascript - IndexedDb 支持哪些数据类型?

progressive-web-apps - 如何使用 Service Worker 和 srcset 创建离线应用?

javascript - 如何注册来自不同子域的服务 worker

javascript - 如何将跟踪事件推送到serviceWorker中?

javascript - Chrome 中的 Firebase Cloud Messaging Service Worker 重定向

javascript - 找不到在离线 Web 应用程序中存储用于离线下载的文件的方法

javascript - IndexedDB:未捕获( promise )DOMException

javascript - 如何在 Metrostyle Javascript 中使用索引数据库