【问题标题】:how to cache ajax response by using serviceWorker如何使用 serviceWorker 缓存 ajax 响应
【发布时间】:2020-04-13 17:59:52
【问题描述】:

我在 index.html 中使用 ajax 调用服务器数据。它完美地获取了这些数据。现在,我正在与服务人员一起工作。我可以缓存所有静态资产(图像、js、css)并在 Chrome 开发工具的应用程序选项卡的缓存存储中检查这些缓存的资产。我可以在“网络”选项卡中看到这些资产也被缓存(磁盘缓存)。

现在,我想使用 service worker 缓存那些 ajax 响应(图像文件数组)。在网络选项卡中,我可以看到它正在调用未缓存的 url(类型:xhr)。到目前为止,我已经尝试获取 url 并缓存这些但无法做到。

这是我在 index.html 中的 ajax 调用

    <script type="text/javascript">
       $(document).ready(function () {
          var url = 'index.cfm?action=main.appcache';
            $.ajax({
                type:"GET",
                url: url,
                data: function(data){
                var resData = JSON.stringify(data);
            },
            cache: true,
            complete: doSomething
            })
});

function doSomething(data) {
    console.log(data.responseText);
}
</script>

这是我的 serviceWorker 获取事件:

    self.addEventListener('fetch', (event) => {

  if (event.request.mode === 'navigate') {
    event.respondWith((async () => {
      try {
        const preloadResponse = await event.preloadResponse;
        if (preloadResponse) {
          return preloadResponse;
        }
        const normalizedUrl = new URL(event.request.url);
        if(normalizedUrl.endsWith === 'index.cfm?action=main.appcache'){
           const fetchResponseP = fetch(normalizedUrl);
           const fetchResponseCloneP = fetchResponseP.then(r => r.clone());
          event.waitUntil(async function() {
           const cache = await caches.open(precacheName);
           await cache.put(normalizedUrl, await fetchResponseCloneP);
            }());
          return (await caches.match(normalizedUrl)) || fetchResponseP;
        }
        const networkResponse = await fetch(event.request);
        return networkResponse;
      } catch (error) {
        console.log('Fetch failed; returning offline page instead.', error);

        const cache = await caches.open(precacheName);
        const cachedResponse = await cache.match(offlineDefaultPage);
        return cachedResponse;
      }
    })());
  }
});

请帮助我缓存响应需要哪些更改。

【问题讨论】:

  • 对此有何建议?
  • 我可以看到从网络选项卡调用的请求,但在缓存中看不到响应

标签: javascript jquery html ajax service-worker


【解决方案1】:

您的 fetch 事件处理程序以

开头
if (event.request.mode === 'navigate') {
  // ...
}

这意味着其中的代码只有在传入的fetch 事件是针对navigation request 时才会执行。只有第一次加载页面时对 HTML 文档的初始请求是导航请求。您对其他子资源的 AJAX 请求不是导航请求。

如果您想缓存您对index.cfm?action=main.appcache 的请求,除了您的导航请求逻辑,您可以在第一个语句之后添加另一个if 语句,并检查该 URL:

self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    // ...
  }

  if (event.request.url.endsWith('index.cfm?action=main.appcache')) {
    // Your caching logic goes here. See:
    // https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook#serving-suggestions
  }
});

【讨论】:

  • 感谢您的大力帮助。我想在初始加载时将该响应加载到页面中意味着导航时间
猜你喜欢
  • 1970-01-01
  • 2018-05-08
  • 2014-01-07
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
相关资源
最近更新 更多