【问题标题】:PWA: Exclude caching in some part of applicationPWA:在应用程序的某些部分排除缓存
【发布时间】:2019-09-30 08:07:21
【问题描述】:

在一个 Angular 应用程序中,我有一个像这样被缓存的 URL 端点:

// ngsw-config.json
"dataGroups": [{
      "name": "api-performance",
      "urls": [
        "https://my-api.com/v1/languages",
      ],
      "cacheConfig": {
        "strategy": "performance",
        "maxSize": 300,
        "maxAge": "1d"
      }
    }
  ]

当客户进行调查过程时,它在离线场景中完美运行。但是在管理面板中,当我尝试更新语言信息时,确实 - 它确实更新了数据库中的记录,但是当我尝试刷新数据时,它不会将请求发送到我们的端点,而是将缓存存储在浏览器中.

这是我尝试过的:

getLanguages(shouldCache: boolean): Promise<any> {
    if (shouldCache) {
      return this.httpClient.get('https://my-api.com/v1/languages').toPromise();
    } else {
      const headers = new HttpHeaders({
        'Cache-Control': 'no-cache, no-store, must-revalidate, post-check=0, pre-check=0',
        'Pragma': 'no-cache',
        'Expires': '0'
      });
      return this.httpClient.get('https://my-api.com/v1/languages', { headers: headers }).toPromise();
    }
  }

不幸的是,它不起作用。我也想过更新缓存,但我不知道怎么做。

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: angular caching service-worker progressive-web-apps


    【解决方案1】:

    您正在使用 performance 模式和 1 天 maxAge,如果可用,它总是从缓存中提供值。一天后您会看到数据发生变化。

    相反,您可以使用freshness 模式或在performance 模式下减少maxAge

    您的手动完成请求不适用,因为 URL https://my-api.com/v1/languages 缓存在 service worker 中。请求中的缓存操作都不起作用,因为请求缓存和服务工作者缓存是不同的缓存层。

    来自 Angular docs

    Angular Service Worker 可以对数据资源使用两种缓存策略中的任何一种。

    性能,默认值,会针对尽可能快的响应进行优化。如果缓存中存在资源,则使用缓存版本,不进行网络请求。这允许一些陈旧,取决于 maxAge,以换取更好的性能。这适用于不经常变化的资源;例如,用户头像图像。

    新鲜度优化数据流通性,优先从网络获取请求的数据。只有当网络超时时,根据超时,请求才会回退到缓存中。这对于频繁更改的资源很有用;例如,帐户余额。

    【讨论】:

      【解决方案2】:

      首先,您需要了解 Service Worker 层与前端和服务器是分离的。它位于中间并拦截所有网络请求,以便您决定如何处理它们。

      服务工作者获取事件处理程序有一个参数,事件。

      您可以“解析”此对象以获取有关请求、event.request 的信息并决定应如何处理。

      例如,您很可能不想缓存 POST、PUT 或 DELETE 请求,因此只需通过调用 fetch 将这些请求传递到网络。仅测试 GET 请求,以简化此操作。

      self.addEventListener("fetch", event => {
      
        event.respondWith(
      
          if(event.request.mode === "GET") {
      
            //compare URL against rules table
            //perform caching strategy for this URL
      
          } else {
      
            return fetch(event);
      
          }
        );
      });
      

      如果您可能有要应用到 URL 的缓存策略,那么您需要查看可能要应用的策略。 FWIW,我可能会采用大约 25 种不同的策略,所以我会尽量简化。

      这是我将 URL 与缓存策略匹配的方法示例:

      function testRequestRule( request, rules ) {
      
        for ( let i = 0; i < rules.length; i++ ) {
      
            if ( rules[ i ].route && rules[ i ].route.test( request.url ) ) {
                return rules[ i ];
            } else if ( rules[ i ].destination &&
                rules[ i ].destination === request.destination ) {
                return rules[ i ];
            }
      
        }
      
      }
      

      这是一个规则对象的样子:

      let routeRules = [ {
          "route": /img\/products\//,
          "strategy": "cacheFallingBackToNetworkCache",
          "options": {
              cacheName: prodPhotos,
              fallback: offlineProductPhoto
          }
      },....]
      

      然后我将对请求执行所需的策略:

          if ( rule.strategy ) {
      
              switch ( rule.strategy ) {
      
                  case "cacheFallingBackToNetwork":
      
                      return responseManager.cacheFallingBackToNetworkCache(
                          event.request, rule.cacheName || cacheName,
                          rule.options.fallback );
      
                  case "fetchAndRenderResponseCache":
      
                      return responseManager.fetchAndRenderResponseCache( {
                              request: event.request,
                              pageURL: rule.options.pageURL,
                              template: rule.options.template,
                              api: rule.options.api,
                              cacheName: rule.cacheName || cacheName
                          } )
                          .then( response => {
      
                              invalidationManager.cacheCleanUp( rule.cacheName || cacheName );
      
                              return response;
      
                          } );
      
                  case "cacheOnly":
      
                      return responseManager.cacheOnly( event.request, rule.cacheName || cacheName )
                          .then( response => {
      
                              invalidationManager.cacheCleanUp( rule.cacheName || cacheName );
      
                              return response;
      
                          } );
      
                  case "networkOnly":
      
                      return responseManager.networkOnly( event.request );
      
                  case "custom":
      
                      return rule.options.handler( event, rule );
      
                  default:
      
                      return responseManager
                          .cacheFallingBackToNetworkCache( event.request,
                              rule.cacheName || cacheName,
                              rule.options.fallback )
                          .then( response => {
      
                              invalidationManager.cacheCleanUp( rule.cacheName || cacheName );
      
                              if ( response ) {
                                  return response;
                              } else {
                                  return simpleFetch( event );
                              }
      
                          } )
                          .catch( error => {
                              console.error( "fetch error: ", error );
                              console.error( "url: ", event.request.url );
                          } );
      
              }
      
          } else {
      
              return simpleFetch( event );
      
          }
      

      简而言之,您可以控制每个网络请求的处理方式,这就是 service worker 的美妙之处。你只需要创建逻辑来处理这个问题,并且没有什么灵丹妙药可以让你成为一名优秀的服务人员。您必须自己编写代码,当然还要对其进行测试。 :)

      【讨论】:

        猜你喜欢
        • 2011-01-29
        • 2017-07-30
        • 1970-01-01
        • 1970-01-01
        • 2012-02-11
        • 1970-01-01
        • 2014-04-07
        • 1970-01-01
        • 2019-07-30
        相关资源
        最近更新 更多