Post

网页总是显示旧内容,无法加载到新内容

网页总是显示旧内容,无法加载到新内容

问题

Chrome浏览器,用“正常模式” vs. “隐私模式”打开同一个url网页,可以看到“正常模式”缺少了最新发布的内容。

image-20250412081106126

怀疑是缓存问题导致,于是将网络断开并刷新。发现“正常模式”打开的依然有内容,因此可以判断是缓存导致。

image-20250412081116596

分析

Disable Cache

image-20250412081831255

在开发者模式下,勾选Disable cache并刷新,依然有内容提供。

Unregister Service Worker

image-20250412082406025

在开发者模式下,点开Application,勾选

  • Update on reload
  • Bypass for network

然后点击Unregister,

image-20250412082547043

显示成功删除,再刷新网页即可查看到最新内容。

image-20250412082701259

总结

Service Worker 是一种运行在浏览器背后的、与网页分离的 独立线程,它赋予 Web 应用一些原本只有原生应用才能做到的功能,比如:


一、主要用途

1. 离线访问能力(离线缓存)

  • Service Worker 可以拦截并缓存网页请求,使用户即使断网,也能访问之前缓存的内容。
  • 常用于 PWA(Progressive Web App)中,实现“断网可用”。

2. 网络请求拦截与控制(代理作用)

  • 可拦截页面发出的 HTTP 请求(fetch 请求),决定是否从缓存、网络或自定义方式返回响应。
  • 允许你做“按需更新”、“缓存优先”、“网络优先”等策略。

3. 后台推送(Push Notification)

  • 支持 Web Push Notification,即便页面未打开,仍可接收服务器推送的消息(前提是用户授权)。

4. 后台同步(Background Sync)

  • 当用户在离线状态进行操作(如发送消息、填写表单),可在重新联网后自动同步数据。

5. 性能优化

  • 减少对服务器的依赖(如图片、本地 JS/CSS 静态资源可缓存),提升访问速度。

二、工作机制概览

1
2
3
4
5
6
7
8
9
+--------------------+           +---------------------------+
|      页面(UI)     |   <---->   |   Service Worker(线程)   |
+--------------------+           +---------------------------+
                                      |
                                      |(网络请求)
                                      v
                               +-----------------+
                               |   网络或缓存响应   |
                               +-----------------+
  • 生命周期管理: Service Worker 需显式注册和激活;
  • 作用域隔离: 一个 Service Worker 只能控制注册它的路径范围内的页面;
  • 异步编程模型: 使用 Promise 和事件监听机制(如 fetch、install、activate)。

三、典型应用示意

以离线网页为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 简化版本
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('v1').then(cache =>
      cache.addAll(['/index.html', '/styles.css', '/logo.png'])
    )
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then(response =>
      response || fetch(event.request)
    )
  );
});

这段代码做了什么?

  • 第一次加载时缓存核心资源;
  • 后续访问时,若找不到网络,就从缓存返回资源,实现“断网可用”。

四、Service Worker 与浏览器缓存的区别

特性浏览器 HTTP 缓存Service Worker
控制粒度HTTP 响应头控制JS 脚本可控,策略灵活
离线访问支持受限(取决于缓存规则)完整支持
是否可拦截请求是(fetch 拦截)
生命周期控制无,自动过期有,需安装、激活、更新
是否支持推送通知是(结合 Push API)

五、为什么要谨慎使用或管理 Service Worker?

  • 缓存更新不及时可能导致“内容旧、打不开、卡页面”;
  • 开发调试时容易被缓存干扰;
  • 安全性要求高(只能在 HTTPS 下运行);
  • 对调试者来说,如果不熟悉其行为,会导致“断网还能访问网页”的错觉。

如果在部署自己的网站时启用了 PWA 或类似离线缓存功能,也建议设计好缓存更新策略(如 stale-while-revalidate 或 version-based cache busting),避免用户加载旧内容。

This post is licensed under CC BY 4.0 by the author.

支持创作者

如果本文帮助到你,可以通过以下收款码支持我:

收款码

感谢你的支持!