You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Service Worker代码缓存路由至index.php的HTML页面实现离线访问

实现圣经网站的完全离线可用(含HTML页面缓存)

看起来你已经搭好了基础的Service Worker静态资源缓存逻辑,现在要把HTML页面也纳入缓存体系,实现网站完全离线可用其实并不复杂——毕竟你的所有页面都是通过index.php根据REQUEST_URI路由返回内容的,只要针对性调整缓存策略就能搞定。

下面是修改后的完整Service Worker代码,我会在代码后逐一解释核心调整点:

var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
  '/', // 预缓存首页HTML
  '/verse/_verse.js',
  '/verse/_verse.css',
  '/home/_home.js',
  '/home/_home.css',
  '/bookmarks/_bookmarks.js',
  '/bookmarks/_bookmarks.css',
  '/search/_search.js',
  '/search/_search.css'
];

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        // 安装阶段先缓存首页和所有静态资源
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('fetch', function(event) {
  const request = event.request;

  // 识别HTML页面请求:导航类请求 + 明确请求HTML资源的GET请求
  const isHtmlRequest = request.mode === 'navigate' || 
                        (request.method === 'GET' && 
                         request.headers.get('accept')?.includes('text/html'));

  event.respondWith(
    caches.match(request)
      .then(function(cachedResponse) {
        // 缓存命中直接返回
        if (cachedResponse) {
          console.log('Returning cached content for:', request.url);
          return cachedResponse;
        }

        // 无缓存则发起网络请求
        return fetch(request)
          .then(function(networkResponse) {
            // 仅缓存状态正常的响应(200成功/304未修改)
            if (networkResponse && (networkResponse.status === 200 || networkResponse.status === 304)) {
              // 缓存HTML页面和预定义的静态资源
              if (isHtmlRequest || urlsToCache.includes(request.url)) {
                const responseToCache = networkResponse.clone();
                caches.open(CACHE_NAME)
                  .then(function(cache) {
                    cache.put(request, responseToCache);
                    console.log('Cached new resource:', request.url);
                  });
              }
            }

            return networkResponse;
          })
          // 离线降级处理:HTML请求无缓存时返回首页,静态资源返回提示
          .catch(function() {
            if (isHtmlRequest) {
              return caches.match('/'); // 离线时用首页作为兜底
            }
            return new Response('离线状态下无法获取该资源', { status: 503 });
          });
      })
  );
});

核心修改点说明

  • 预缓存首页:在urlsToCache数组中加入'/',确保用户首次访问时,首页HTML就被存入缓存。
  • 精准识别HTML请求:通过request.mode === 'navigate'(用户输入URL、点击链接这类导航行为)和请求头accept包含text/html,精准判断哪些请求是需要缓存的HTML页面。
  • 动态缓存HTML响应:网络请求成功后,自动将用户访问过的所有HTML页面(比如/verse、/home等路由)存入缓存,下次访问相同路由时,离线状态下直接返回缓存内容。
  • 离线降级策略:如果用户离线时请求了未缓存的页面,我们返回预缓存的首页作为兜底;静态资源未缓存则返回明确的离线提示,提升用户体验。
  • 兼容动态路由:Service Worker会根据完整的请求URL(如/bookmarks)缓存对应的HTML响应,完美适配你基于REQUEST_URI的路由规则。

额外注意事项

  • 缓存版本管理:当网站内容更新时,记得修改CACHE_NAME(比如改成my-site-cache-v2),触发Service Worker重新安装,替换旧缓存。
  • 避免缓存无效内容:只缓存状态码为200或304的响应,确保缓存的都是有效页面和资源。
  • 测试离线效果:可以在Chrome DevTools的「Application → Service Workers」中勾选「Offline」,模拟离线状态验证功能。

内容的提问来源于stack exchange,提问作者Chud37

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 21:28:13