当前位置: 首页 > news >正文

Service Worker 实现离线应用思路

1 背景

本地运行一个vue项目,界面如下:
在这里插入图片描述
使用 Service Worker 对其进行缓存,预期在停止运行项目时(模拟离线场景)也能够正常访问项目

2 缓存的资源分析

检查 network,浏览器访问:http://localhost:5173/ 时,获取的资源需要包含如下,才能正常展示界面:

  • HTML 文件
  • JS 文件
  • CSS 文件

3 index.html 内容

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <div
      style="
        background-color: #fff;
        border-radius: 10px;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        width: 300px;
        padding: 20px;
        text-align: center;
        transition: transform 0.3s ease;
      "
    >
      <img
        src="https://via.placeholder.com/280x150"
        alt="Card Image"
        style="width: 100%; border-radius: 8px; height: auto"
      />
      <h2 style="margin: 20px 0; font-size: 1.5rem">Card Title</h2>
      <p style="font-size: 1rem; color: #555; margin-bottom: 20px">
        This is a simple card with an image, title, and description. It uses inline styles.
      </p>
      <button
        style="
          background-color: #007bff;
          color: white;
          border: none;
          padding: 10px 20px;
          font-size: 1rem;
          border-radius: 5px;
        "
      >
        Click Me
      </button>
    </div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

4 注册/删除 Service Worker

在 index.html 中注册Service Worker

      // 注册 Service Worker 检查浏览器是否支持 Service Worker
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
          navigator.serviceWorker
            .register('/service-worker.js') // 注册 Service Worker
            .then((registration) => {
              console.log('Service Worker 注册成功:', registration)
            })
            .catch((error) => {
              console.log('Service Worker 注册失败:', error)
            })
        })
      }
      // 删除 Service Worker
      if ('serviceWorker' in navigator) {
        // 获取当前注册的 Service Worker
        navigator.serviceWorker.getRegistration().then((registration) => {
          if (registration) {
            // 注销 Service Worker
            registration.unregister().then((boolean) => {
              if (boolean) {
                console.log('Service Worker 已成功注销')
              } else {
                console.log('Service Worker 注销失败')
              }
            })
          } else {
            console.log('没有找到已注册的 Service Worker')
          }
        })
      }

5 service-worker.js 文件

const CACHE_NAME = 'my-app-cache-v1' // 缓存的名称
const URLS_TO_CACHE = [
  '/', // HTML 根页面
  '/src/main.ts', // JS 文件   由于是本地模拟,所以是 /src/
  '/src/assets/main.css' // CSS 文件    由于是本地模拟,所以是 /src/
]

// 安装 Service Worker 时,缓存指定的资源
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => {
      console.log('缓存文件...')
      return cache.addAll(URLS_TO_CACHE)
    })
  )
})

// 拦截请求并返回缓存数据(如果有)
self.addEventListener('fetch', (event) => {
  console.log('event.request.url ', event.request.url)
  event.respondWith(
    caches.match(event.request, { ignoreSearch: true }).then((cachedResponse) => { // 设置 ignoreSearch: true 来忽略查询参数,例如,/index.html 和 /index.html?version=1 将被视为相同。
      // 如果缓存中有匹配的响应,则返回缓存
      if (cachedResponse) {
        console.log('从缓存中提供:', event.request.url)
        return cachedResponse
      }
      console.log('从网络中提供:', event.request.url)
      // 如果缓存中没有,发送网络请求
      return fetch(event.request)
    })
  )
})

当 Service Worker 安装时,它会缓存资源(如 html、css、.js 等)
缓存的资源包含:

const URLS_TO_CACHE = [
  '/', // HTML 根页面
  '/src/main.ts', // JS 文件   由于是本地模拟,所以是 /src/
  '/src/assets/main.css' // CSS 文件    由于是本地模拟,所以是 /src/
]

当缓存这些资源后,后续请求url如果匹配到了就可以返回,如:

  • ‘http://localhost:5173/src/’ 会匹配到 ‘/’
  • ‘http://localhost:5173/src/main.ts/’ 会匹配到 ‘/src/main.ts’

缓存的资源在cache中可以查看
在这里插入图片描述

离线

停止运行项目,模拟离线场景,输入 http://localhost:5173/ 进入项目,可以看到项目正常展示
在这里插入图片描述
网络请求中可以看到, html js css 都是通过 serviceworker 返回的缓存
在这里插入图片描述

相关文章:

  • 简识Kafka集群与RocketMQ集群的核心区别
  • 网络安全研究
  • 在运维工作中,磁盘文件满了,怎么办?
  • 綫性與非綫性泛函分析與應用_2.賦范向量空間-母本
  • Java——抽象类
  • 快速排序与归并排序模板
  • 深入解析DeepSeek智慧城市应用中的交通流量预测API接口
  • 本地部署deepseek-r1 ollama+anythingllm
  • `pip freeze > requirements.txt` 命令
  • 数据治理与管理
  • 从零开始的网站搭建(以照片/文本/视频信息通信网站为例)
  • 大白话React第二章深入理解阶段
  • PTA习题(C语言)
  • Linux——安装Git的方法
  • 一、Spring框架系统化学习路径
  • devops-Jenkins一键部署多台实例
  • 【C++】模版
  • 《AI赋能星际探索:机器人如何开启宇宙新征程!》
  • Milvus向量数据库可视化客户端Attu
  • 基于时间序列的预测方法进行异常值检测概述
  • 村级网站建站/营销团队找产品合作
  • 怎么看网站后台什么语言做的/武汉seo首页优化技巧
  • 国外设计网站app/如何去除痘痘有效果
  • 福州建设工程质量监督网站/b2b自动发布信息软件
  • 普陀企业网站建设/外链平台
  • 广州网站推广策划/北京网站优化培训