【问题标题】:Service worker offline support with pushstate and client side routing具有 pushstate 和客户端路由的 Service Worker 离线支持
【发布时间】:2017-12-31 18:33:19
【问题描述】:

我正在使用服务人员为我的单页网络应用程序引入离线功能。这非常简单 - 在可用时使用网络,如果没有,请尝试从缓存中获取:

service-worker.js:

self.addEventListener("fetch", event => {
    if(event.request.method !== "GET") {
        return;
    }
    event.respondWith(
        fetch(event.request)
            .then(networkResponse => {
                var responseClone = networkResponse.clone();
                if (networkResponse.status == 200) {
                    caches.open("mycache").then(cache => cache.put(event.request, responseClone));
                }
            return networkResponse;
        })
        .catch(_ => {
            return caches.match(event.request);
        })
    )
})

因此它会拦截所有 GET 请求并缓存它们以供将来使用,包括初始页面加载。

在 DevTools 中切换到“离线”并在应用程序的根目录处刷新按预期工作。

但是,我的应用使用 HTML5 pushstate 和客户端路由器。用户可以导航到新路由,然后下线,然后点击刷新,将收到“无互联网”消息,因为服务工作者从未被告知此新 URL。

我想不出办法。与大多数 SPA 一样,我的服务器被配置为为许多包罗万象的 URL 提供 index.html。我需要为服务人员提供某种类似的行为。

【问题讨论】:

    标签: javascript html service-worker


    【解决方案1】:

    在您的fetch 处理程序中,您需要检查event.request.mode 是否设置为'navigate'。如果是这样,它是一个导航,而不是响应与特定 URL 匹配的缓存响应,您可以响应您的index.html 的缓存响应。 (或app-shell.html,或您用于 SPA 的通用 HTML 的任何 URL。)

    您更新后的 fetch 处理程序大致如下:

    self.addEventListener('fetch', event => {
      if (event.request.method !== 'GET') {
        return;
      }
    
      if (event.request.mode === 'navigate') {
        event.respondWith(caches.match('index.html'));
        return;
      }
    
      // The rest of your fetch handler logic goes here.
    });
    

    这是服务工作者的常见用例,如果您希望使用预打包的解决方案,workbox-routing module 中的NavigationRoute class 可以为您自动执行。

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 2019-05-09
    相关资源
    最近更新 更多