【问题标题】:Responding to fetch request via cache xor indexedDB通过缓存 xor indexedDB 响应获取请求
【发布时间】:2018-07-24 20:36:08
【问题描述】:

我正在尝试让服务人员根据发出的请求类型响应 fetch 事件。对于静态资源,我使用缓存:

// TODO: make cache update when item found
const _fetchOrCache = (cache, request) => {
  return cache.match(request).then(cacheResponse => {

    // found in cache
    if (cacheResponse) {
      return cacheResponse
    }

    // has to add to cache
    return fetch(request)
      .then(fetchResponse => {
        // needs cloning since a response works only once
        cache.put(request, fetchResponse.clone())
        return fetchResponse
      });
  }).catch(e => { console.error(e) })
}

对于 api 响应,我已经将 IndexedDB 与 Jake Archibald 的 IndexedDB 连接起来,承诺返回如下内容:

const fetchAllItems = () => {
    return self.idbPromise
        .then(conn => conn.transaction(self.itemDB, 'readonly'))
        .then(tx => tx.objectStore(self.itemDB))
        .then(store => store.getAll())
        .then(storeContents => JSON.stringify(storeContents));
}

当我调用服务工作者中的所有内容时,缓存部分工作,但 indexedDB 惨遭失败,抛出无法在 api url 获取的错误:

self.addEventListener("fetch", event => {

    // analyzes request url and constructs a resource object
    const resource = getResourceInfo(event.request.url);

    // handle all cachable requests
    if (resource.type == "other") {
        event.respondWith(
            caches.open(self.cache)
                .then(cache => _fetchOrCache(cache, event.request))
        );
    }

    // handle api requests
    if (resource.type == "api") {
        event.respondWith(
            new Response(fetchAllItems());
        );    
    }
});

我的问题如下:
1.) 像这样分离存储获取请求有什么意义吗?
2.) 如何使 indexedDB 部分工作?

【问题讨论】:

    标签: javascript fetch service-worker indexeddb cachestorage


    【解决方案1】:

    很好地了解使用基于 Jake Archibalds 承诺的 idb。有很多方法可以安装他的 idb。最快的 - 在某处下载 idb.js 文件(这是库)。然后像这样在 service worker 的第一行导入它:

        importScripts('./js/idb.js');
    
        .....
    
        //SW installation event
        self.addEventListener('install', function (event) {
            console.log("[ServiceWorker] Installed");
        });
    
    
        //SW Actication event (where we create the idb)
        self.addEventListener('activate', function(event) {
            console.log("[ServiceWorker] Activating");
            createIndexedDB();
        });
    
    
       .....
    
       //Intercept fetch events and save data in IDB
    
       .....
    
    
        //IndexedDB
        function createIndexedDB() {
          self.indexedDB = self.indexedDB || self.mozIndexedDB || self.webkitIndexedDB || self.msIndexedDB;
    
          if (!(self.indexedDB)) { console.console.log('IDB not supported'); return null;}
    
          return idb.open('mydb', 1, function(upgradeDb) {
            if (!upgradeDb.objectStoreNames.contains('items')) {
              upgradeDb.createObjectStore('items', {keyPath: 'id'});
            }
          });
        }
    

    从上面粘贴的用于检索 IDB 数据的代码来看,我不清楚 idbPromise 到底是什么......你确定你声明了这个变量吗?

    你应该有这样的东西

    importScripts('./js/idb.js');
    
    //...
    //createIdb and store
    //...
    
    var idbPromise = idb.open('mydb');
    
    //and after that you have your code like idbPromise.then().then()...
    

    因此,您在 SW 激活期间创建 IDB 和表。之后,您拦截 fetch 事件并开始使用 indexeddb,就像您在教程中看到的那样。

    祝你好运

    【讨论】:

    • 感谢您的回答,我应该包括代码本身已经导入和连接。这是我遇到问题的获取部分。将更新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 2023-03-06
    • 2023-04-10
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多