由于 FreeCDN 不是很符合主题的需求,所以本文中移除了 FreeCDN ,手动进行实现了 ServiceWorker 增加了全站离线缓存的功能,支持博客的离线访问。

一、配置方法

使用前提:网站开启了 HTTPS

ServiceWorker 脚本必须与网站同域,且在网站根目录,且网站不能存在证书问题,否则将无法正常注册使用,所以需要添加如下转发配置。

打开 Nginx 的配置文件,添加如下转发配置:

    location ~ ^/sw.min.js {
      rewrite ^/(.*) /themes/dream/source/js/$1 break;
      proxy_pass http://localhost:8090;
      proxy_set_header HOST $host;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

使配置生效:

# 检查配置正确性
nginx -t

# 重新加载配置
nginx -s reload

通过 https://域名/sw.min.js 能够成功访问到文件即配置成功。

二、功能介绍

2.1 CDN 并发请求

这是 SW 要做的第一件事,一些免费 CDN 目前可能不是很稳定,例如 jsDeliverSW 中收集了多个 CDN 源,将一个请求转换成并发对多个CDN源的请求,然后以最早响应的请求为准,获得响应后 SW 将对请求进行缓存。这么做出了避免 CDN 源站异常外,也为了提高网站访问速度。

SW 开启成功后首次请求将看到一个文件被多次请求,有的请求被放弃了(红色请求)。

CDN 并发请求效果

2.2 全站离线

通过 SW 可以实现对网站所有的 GET 请求进行离线缓存,包括请求地址非本站的请求。当无法访问服务器时,通过读取缓存进行网站的访问。

但是开启全站缓存后缓存的资源增多,更占用空间,网站每次请求都将进行一次缓存更新,且这些缓存只有在访问服务器失败后才会被访问。虽然缓存更新带来的耗时几乎可以忽略不计,但是如今的用户一般也不会出现断网的情况吧?除非网站炸了,所以全站缓存实用性不大,所以这是一个可选项。

只有被访问过的页面有缓存,才可以离线访问。

对网站的请求是失败的,但是不影响网站的打开和访问。

全站离线效果

2.3 卸载

Service Worker 不能直接删除 sw.min.js 脚本关闭,取消安装需要调用取消安装的脚本。选中卸载一天左右,然后才可以更改回 关闭 选项。

nginx 上的转发配置可以删除。

三、实现原理

如果你对实现原理感兴趣的话,可以看看这篇文章:

Service Worker 是一个服务器与浏览器之间的中间人角色,它可以拦截网络请求并根据网络具体情况采取适当的动作、更新来自服务器的的资源。本文通过 Service Worker 代理请求,实现网页第二次访问的离线访问和CDN并发请求功能,提高网站的访问速度,同时能够避免 jsDeliver 这类 CDN 问题造成的网站不可用的情况。