【问题标题】:Bypass default caching policy if file is managed by service worker如果文件由服务工作者管理,则绕过默认缓存策略
【发布时间】:2018-07-03 13:35:36
【问题描述】:

我正在使用 Google 的 workbox-cli 工具来预缓存我网站上的一些文件。是否可以将网络服务器设置为默认在所有文件的 HTTP 响应标头中返回以下内容:

cache-control: s-maxage=2592000, max-age=86400, must-revalidate, no-transform, public

但是,只有当文件将被服务工作人员预缓存时,才让网络浏览器使用以下命令:

cache-control: s-maxage=2592000, max-age=0, must-revalidate, no-transform, public

所以,我希望服务人员在预缓存文件之前将网络服务器响应标头中的max-age=86400 更改为max-age=0。这使得服务工作者从网络服务器获取已根据sw.js 中的修订更改的文件,而不是从本地缓存中检索它们。默认情况下,任何不受 Service Worker 管理的文件都会缓存 86400 秒。

一些背景资料

目前,我正在使用以下 bash 脚本来设置我的sw.js

#!/bin/bash
if [ ! -d /tmp/workbox-configuration ]; then
mkdir /tmp/workbox-configuration
fi
cat <<EOF > /tmp/workbox-configuration/workbox-config.js
module.exports = {
  "globDirectory": "harp_output/",
  "globPatterns": [
EOF
( cd harp_output && find assets de en -type f ! -name "map.js" ! -name "map.json" ! -name "markerclusterer.js" ! -name "modal.js" ! -name "modal-map.html" ! -name "service-worker-registration.js" ! -name "sw-registration.js" ! -path "assets/fonts/*" ! -path "assets/img/*-1x.*" ! -path "assets/img/*-2x.*" ! -path "assets/img/*-3x.*" ! -path "assets/img/maps/*" ! -path "assets/img/video/*_1x1.*" ! -path "assets/img/video/*_4x3.*" ! -path "assets/js/workbox-*" ! -path "assets/videos/*" ! -path "de/4*" ! -path "de/5*" ! -path "en/4*" ! -path "en/5*" | sort | sed 's/^/"/' | sed 's/$/"/' | sed -e '$ ! s/$/,/' >> /tmp/workbox-configuration/workbox-config.js )
cat <<EOF >> /tmp/workbox-configuration/workbox-config.js
  ],
  "swDest": "/tmp/workbox-configuration/sw.js"
};
EOF
workbox generateSW /tmp/workbox-configuration/workbox-config.js
sed -i 's#^importScripts(.*);$#importScripts("/assets/js/workbox-sw.js");\nworkbox.setConfig({modulePathPrefix: "/assets/js/"});#' /tmp/workbox-configuration/sw.js
sed -i 's/index.html"/"/' /tmp/workbox-configuration/sw.js
uglifyjs /tmp/workbox-configuration/sw.js -c -m -o harp_output/sw.js

在我的 Nginx 网络服务器上,默认情况下会提供以下 HTTP 标头:

more_set_headers "cache-control: s-maxage=2592000, max-age=0, must-revalidate, no-transform, public";

但是,如果请求的资源没有被 service worker 处理,默认的cache-control 设置会被覆盖:

location ~ ^/(assets/(data/|fonts/|img/(.*-(1|2|3)x\.|maps/|video/.*_(1x1|4x3)\.)|js/(map|markerclusterer|modal|service-worker-registration|sw-registration)\.js|videos/)|(de|en)/((4|5).*|modal-map\.html)) {
    more_set_headers "cache-control: s-maxage=2592000, max-age=86400, must-revalidate, no-transform, public";
}

当前方法的问题(参见背景信息)

  1. 我必须跟踪文件并更新nginx.confcorrespondingly。
  2. max-age=0 也用于不支持服务工作者的网络浏览器。因此,他们会在每次访问页面时向网络服务器请求资源。

第一次更新

我想要的预缓存行为可以用两个workbox strategies 来说明。我希望服务工作者显示以下行为,如场景 1 和 2 中所述,尽管 cache-control: max-age=86400 是由网络服务器在 HTTP 标头中为资产(例如 default.js)提供的。

场景 1:sw.js 中的修订没有改变

网页被访问,sw.js 文件由于max-age=0 而从网络服务器检索,并且网络浏览器注意到default.js 的修订版没有改变。在这种情况下,default.js 是从预缓存缓存中检索的:

场景 2:sw.js 中的修订确实发生了变化

访问网页,由于max-age=0,从网络服务器检索sw.js文件,并且网络浏览器注意到default.js的修订版本发生了变化。在这种情况下,default.js 是从网络服务器检索到的:

第二次更新

基本上,所需的策略类似于network-first strategy。但是,只有在 sw.js 中文件的修订版本发生变化时才执行第 2 步。

第三次更新

如果我没记错的话,上面已经有some work了:

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(`static-${version}`)
      .then(cache => cache.addAll([
        new Request('/styles.css', { cache: 'no-cache' }),
        new Request('/script.js', { cache: 'no-cache' })
      ]))
  );
});

【问题讨论】:

  • developers.google.com/web/tools/workbox/modules/… 也许审查文档可以提供帮助。如果您可以协调安装/重新安装 SW 的事件,并在进程中拖动缓存刷新的项目,那么预缓存可能会从您的盘子中删除一些内容
  • @RobertRowntree 我已经在使用工作箱的预缓存模块。链接的文档不包含任何使服务工作者从网络服务器而不是本地缓存检索更改的资源的设置。

标签: service-worker workbox


【解决方案1】:

我认为您对服务人员的实际工作方式没有足够全面的了解。

您定义一个或多个缓存供 Service Worker 使用。您可以指定缓存中的内容,是否缓存未来的请求等

Service Worker 现在拦截来自客户端的所有网络请求,然后根据您对其进行编程来响应它们。如果可用,它可以返回缓存的内容,通过网络更新时首先缓存内容,网络优先并在没有连接的情况下复制到缓存,缓存图像但不缓存其他任何内容,仅缓存 GET 请求,仅缓存某些域,文件类型等等……

它缓存的内容以及每个缓存的有效时间完全取决于您,并且完全不受服务器响应标头的影响。如果您告诉 Service Worker 对资源进行获取请求,那么它将通过网络加载该资源,而不管任何标头或已在本地缓存的内容。

您可以完全控制整个缓存过程,这非常有用,但也有自己的陷阱。

【讨论】:

    【解决方案2】:

    我在cache-control HTTP 标头中使用了s-max-age 而不是s-maxage,这导致我的反向代理和工作箱服务工作者出现一些意外行为。修复后,Service Worker 工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 2018-08-20
      • 2017-05-24
      • 2020-06-11
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多