【发布时间】: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";
}
当前方法的问题(参见背景信息)
- 我必须跟踪文件并更新
nginx.confcorrespondingly。 -
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 我已经在使用工作箱的预缓存模块。链接的文档不包含任何使服务工作者从网络服务器而不是本地缓存检索更改的资源的设置。