Over dit codelab
1. 欢迎
在本实验中,您将使用一个现有的 Web 应用,并将其设置为可离线使用。这是一系列关于渐进式 Web 应用研讨会的配套 Codelab 中的第一个。本系列中还有 7 个 Codelab。
学习内容
- 手动编写 Service Worker
- 将 Service Worker 添加到现有 Web 应用
- 使用 Service Worker 和 Cache Storage API 将资源设为可离线使用
注意事项
- 基本 HTML 和 JavaScript
所需条件
- 一个支持 Service Worker 的浏览器
2. 进行设置
首先,克隆或下载完成本 Codelab 所需的起始代码:
如果您克隆了代码库,请确保您位于 starter
分支上。该 ZIP 文件中还包含该分支的代码。
此代码库需要 Node.js 14 或更高版本。获得代码后,从命令行的代码文件夹中运行 npm ci
,以安装您需要的所有依赖项。然后,运行 npm start
来启动此 Codelab 的开发服务器。
源代码的 README.md
文件会为所有分布式文件提供说明。此外,下面是此 Codelab 中您将会用到的主要现有文件:
密钥文件
js/main.js
- 主应用 JavaScript 文件service-worker.js
- Application 的 Service Worker 文件
3. 离线测试
在进行任何更改之前,请先测试一下,看看 Web 应用目前是否无法离线使用。为此,请让我们的计算机处于离线状态,然后重新加载 Web 应用,如果您使用的是 Chrome,请执行以下操作:
- 打开 Chrome 开发者工具
- 切换到“应用”标签页
- 切换到“Service Worker”部分
- 选中“离线”复选框
- 刷新页面而不关闭 Chrome 开发者工具
在测试了网站但未能成功加载离线数据后,接下来该添加一些在线功能了!取消选中离线复选框并继续执行下一步。
4. 离线保存
是时候添加基本的 Service Worker!此过程将分两步进行:注册 Service Worker 和缓存资源。
注册 Service Worker
您已经有一个空的 Service Worker 文件,因此,请确保显示更改,让我们在应用中注册该文件。为此,请将以下代码添加到 js/main.js
的顶部:
import swURL from 'sw:../service-worker.js';
// Register the service worker
if ('serviceWorker' in navigator) {
// Wait for the 'load' event to not block other work
window.addEventListener('load', async () => {
// Try to register the service worker.
try {
const reg = await navigator.serviceWorker.register(swURL);
console.log('Service worker registered! 😎', reg);
} catch (err) {
console.log('😥 Service worker registration failed: ', err);
}
});
}
说明
只有在页面加载后,以及网站支持 Service Worker 时,此代码才会注册空的 service-worker.js
Service Worker 文件。
预缓存资源
为了使 Web 应用能够离线工作,浏览器需要能够响应网络请求并选择路由目的地。为此,请将以下内容添加到 service-worker.js
// Choose a cache name
const cacheName = 'cache-v1';
// List the files to precache
const precacheResources = ['/', '/index.html', '/css/style.css', '/js/main.js', '/js/app/editor.js', '/js/lib/actions.js'];
// When the service worker is installing, open the cache and add the precache resources to it
self.addEventListener('install', (event) => {
console.log('Service worker install event!');
event.waitUntil(caches.open(cacheName).then((cache) => cache.addAll(precacheResources)));
});
self.addEventListener('activate', (event) => {
console.log('Service worker activate event!');
});
// When there's an incoming fetch request, try and respond with a precached resource, otherwise fall back to the network
self.addEventListener('fetch', (event) => {
console.log('Fetch intercepted for:', event.request.url);
event.respondWith(
caches.match(event.request).then((cachedResponse) => {
if (cachedResponse) {
return cachedResponse;
}
return fetch(event.request);
}),
);
});
现在,返回到浏览器,关闭预览标签页,然后重新打开。您应该看到与 Service Worker 中的不同事件相对应的 console.log
!
接下来,请再次离线并刷新网站。即使您处于离线状态,也能看到加载成功!
说明
在 Service Worker 的安装事件期间,使用 Cache Storage API 打开命名的缓存。然后,使用 cache.addAll
方法将 precacheResources
中指定的文件和路由加载到缓存中。这称为“预缓存”,因为它在安装期间会预先缓存文件集,而不是在需要或请求时缓存文件。
在 Service Worker 控制网站后,请求的资源会像代理一样通过 Service Worker。每个请求都会触发提取事件,在此 Service Worker 中,在缓存中搜索匹配项(如果有),并返回缓存的资源。如果不匹配,则会正常请求资源。
通过缓存资源,应用可以避免网络请求,从而离线工作。现在,该应用在离线时也能响应 200 状态代码!