【问题标题】:How to use SSR pages when online, and fallback to cached index.html when offline在线时如何使用 SSR 页面,离线时如何回退到缓存的 index.html
【发布时间】:2019-06-04 22:55:18
【问题描述】:

我正在同时使用 Angular PWA 和 Angular Universal,我正在玩离线导航。

我试图为导航请求实现的行为是:

  • 在线时,为服务器端呈现的页面提供最大的首次绘制速度(然后客户端接管)
  • 离线时,回退到缓存的index.html,以便使用缓存的客户端应用

问题在于ngsw-worker.js 及其配置文件ngsw-config.json 没有提供足够高的粒度级别来实现这一点。

这是我当前的ngsw-config.json,它提供了一种接近我想要实现的行为,但是当我在离线模式下刷新应用程序时,它仅在页面在在线模式下被刷新(因此被缓存)时才起作用之前。

{
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/*.css",
          "/*.js"
        ]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
        ]
      }
    }
  ],
  "dataGroups": [
    {
      "name": "backend",
      "urls": [
        "/backend/**"
      ],
      "cacheConfig": {
        "maxSize": 100,
        "maxAge": "3d",
        "strategy": "freshness"
      }
    },
    {
      "name": "serverSideRenderedPages",
      "urls": [
        "/**"
      ],
      "cacheConfig": {
        "maxSize": 100,
        "maxAge": "3d",
        "strategy": "freshness"
      }
    }
  ],
  "navigationUrls": [
    "!/**"
  ]
}

我认为服务人员应该“具有普遍意识”,但如果不是,是否有任何干净的解决方案或解决方法?

【问题讨论】:

    标签: angular progressive-web-apps angular-universal angular-pwa


    【解决方案1】:

    由于框架不提供此功能,我将其作为功能请求提交,一位团队成员(简而言之)告诉我,客户端在线这一事实并不能保证 SSR 页面的渲染速度比加载速度快缓存中的客户端应用程序,这会破坏更新机制,因为 SSR 页面引用的是最新的客户端应用程序。

    有关详细信息,请参阅GitHub issue

    【讨论】:

      【解决方案2】:

      在没有网络连接的情况下,您需要使用 service worker 为用户提供离线页面

      const cacheName = 'cache-v1';
      const offlineUrl = 'offline-page.html';
      
      // Cache our known resources during install
      self.addEventListener('install', event => {
        event.waitUntil(
          caches.open(cacheName)
          .then(cache => cache.addAll([
            './index.html',
            offlineUrl
          ]))
        );
      });
      
      // Cache any new resources as they are fetched
      self.addEventListener('fetch', function(event) {
          event.respondWith(
            caches.match(event.request)
            .then(function(response) {
              if (response) {
                return response;
              }
              var fetchRequest = event.request.clone();
      
              return fetch(fetchRequest).then(
                function(response) {
                  if(!response || response.status !== 200) {
                    return response;
                  }
      
                  var responseToCache = response.clone();
                  caches.open(cacheName)
                  .then(function(cache) {
                    cache.put(event.request, responseToCache);
                  });
      
                  return response;
                }
              ).catch(error => {
                // Check if the user is offline first and is trying to navigate to a web page. If user navigate to another page the website will serve them the offline page
                if (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html')) {
                // Return the offline page
                return caches.match(offlineUrl);
              }
              });
            })
          );
      });
      

      然后把这个脚本放到你的 index.html 中

        <script>
        // Register the service worker
        if ('serviceWorker' in navigator) {
          navigator.serviceWorker.register('./sw.js').then(function(registration) {
            // Registration was successful
          });
        }
        </script>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-07
        • 1970-01-01
        • 2015-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 2016-01-07
        相关资源
        最近更新 更多