
在 Vultr 上设置 Service Worker
Service Worker 提供了一种在 Web 浏览器中运行可脚本化网络代理的方式,允许开发人员控制网页如何响应网络请求、管理资源以及构建健壮且高性能的 Web 应用程序。学习如何在你的 Web 应用程序中使用 Service Worker 将帮助你构建诸如后台数据同步、预取访客接下来需要的资源、在一个地方而不是多个页面处理数据以及其他令人兴奋的功能。
在本文中,我们将了解 Service Worker 的生命周期,以及为什么了解它们的工作原理至关重要。我们还将创建一个托管在 Vultr 上的示例 Web 应用程序,包括通过 Nginx 和 Let's Encrypt 使用 HTTPS,我们需要允许 Service Worker 在访客的浏览器上运行。
Service Worker 生命周期
Service Worker 是由事件驱动的 JavaScript 后台任务,它们与网页的主线程分开运行。它们充当网页和网络之间的中间体,以提供离线支持、推送通知和后台同步等功能。
了解 Service Worker 的生命周期对于在 Web 项目中有效地实施和管理它们至关重要。此生命周期包含三个主要阶段
- 注册:第一步是注册阶段,在此阶段我们检查浏览器是否支持 Service Worker。
- 安装:注册后,当用户访问网站时,Service Worker 会立即下载 用于 Service Worker 控制的 URL,并为指定的 URL 创建缓存。每当网站有新版本时,安装都会被触发,新版本将在后台安装。
- 激活:在激活阶段,Service Worker 开始控制其范围内的网页并开始拦截网络请求。此阶段通常是清理过时缓存和执行任何必要初始化任务的合适阶段。
在 Vultr 上设置项目目录
首先,按照我们上一篇文章中的在 Vultr 上部署服务器部分中的步骤部署服务器。此项目不需要特定的市场应用程序。接下来,让我们继续通过 SSH 访问服务器终端并为我们的 Web 应用程序设置一个项目。我们将制作一个带有 CSS 样式表的登录页面,并在我们的主要 JavaScript 文件中添加一个脚本,该脚本将用于检查浏览器是否支持 Service Worker 并注册 Service Worker。
我们将使用Nano 文本编辑器在服务器上创建和编辑我们的项目文件。你可以查看快捷键备忘单 以获取使用 Nano 的帮助。
- 创建一个项目目录,并导航到其中。bash
mkdir sample cd sample
- 创建一个 HTML 文件。bash
nano index.html
- 将下面的代码复制并粘贴到 index.html 文件中。html
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>My Service Worker App</title> <link rel="stylesheet" href="/main.css" /> </head> <body> <h1>Welcome to My Service Worker App</h1> <p>This is a sample paragraph with <a href="#">a link</a>.</p> <script src="/app.js"></script> </body> </html>
- 保存并退出文件。
- 创建一个 CSS 文件。bash
nano main.css
- 将下面的代码复制并粘贴到 main.css 文件中。css
body, h1 { margin: 0; padding: 0; } h1 { text-align: center; margin-top: 50px; } p { text-align: center; } body { background-color: #add8e6; font-family: Arial, sans-serif; } a { color: #00ff7b; } a:hover { text-decoration: underline; }
- 保存并关闭文件。
创建 Service Worker
现在你已经设置了项目目录,在本节中,你将了解 Service Worker 如何注册、安装和激活。
安装和激活 Service Worker
让我们向我们的项目添加一个基本的 Service Worker,我们的主要 JavaScript 应用程序可以与其交互
- 在
sample
目录中,创建一个 JavaScript 文件bashnano sw.js
- 将下面的代码复制并粘贴到
sw.js
文件中。jsconst CACHE_NAME = "my-cache-v1"; const urlsToCache = ["/", "/index.html", "/main.css"]; self.addEventListener("install", (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { console.log("Opened cache"); return cache.addAll(urlsToCache); }), ); }); self.addEventListener("activate", (event) => { event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames .filter((cacheName) => { return cacheName !== CACHE_NAME; }) .map((cacheName) => { return caches.delete(cacheName); }), ); }), ); }); self.addEventListener("fetch", (event) => { event.respondWith( caches.match(event.request).then((response) => { if (response) { return response; } return fetch(event.request); }), ); });
- 保存并退出文件。
在上面的代码中,我们正在挂接到我们之前描述的三个事件。当触发 install 事件时,我们为我们感兴趣的控制的 URL 打开一个缓存。我们使用 activate 事件来清除我们可能拥有的任何旧缓存。最后,我们有一个 fetch 事件,它检查用户请求的资源是否已缓存;否则,它会从网络获取资源并将其返回。
注册 Service Worker
在本节中,你将学习如何检查浏览器是否支持 Service Worker,添加一个事件侦听器以注册 Service Worker,并在 Service Worker 注册后发出警报。
- 创建一个 JavaScript 文件。bash
nano app.js
- 将下面的代码复制并粘贴到
app.js
文件中。jsif ("serviceWorker" in navigator) { window.addEventListener("load", function () { navigator.serviceWorker .register("/sw.js") .then(function (registration) { alert( "Service Worker registration successful with scope: " + registration.scope, ); if (registration.installing) { console.log("Service worker installing"); } else if (registration.waiting) { console.log("Service worker installed"); } else if (registration.active) { console.log("Service worker active"); } }) .catch(function (err) { alert("Service Worker registration failed: " + err); }); }); }
- 保存并关闭文件。
在上面的代码中,if ('serviceWorker' in navigator)
条件检查浏览器是否支持 Service Worker。如果我们有对 Service Worker 的支持,我们可以使用 navigator.serviceWorker.register()
方法继续注册,方法是提供位于 /sw.js
的脚本。我们正在发送一个打印作用域 URL 并将生命周期状态记录到控制台的警报。
在 Vultr 服务器上提供 Web 应用程序
在本节中,你将学习如何创建一个 systemd 服务,该服务在系统启动时自动启动并运行一个 Python HTTP 服务器,该服务器提供 Web 应用程序。
- 退出
sample
目录。bashcd ..
- 创建一个 Python 文件。bash
nano http_server.py
- 将下面的代码复制并粘贴到
http_server.py
文件中。pythonimport http.server import socketserver import os PORT = 8000 DIRECTORY = "sample" sample_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "sample") mime_types = { ".html": "text/html", ".css": "text/css", ".js": "application/javascript", } class MyHTTPRequestHandler(http.server.SimpleHTTPRequestHandler): def guess_type(self, path): _, ext = os.path.splitext(path) return mime_types.get(ext.lower(), "application/octet-stream") Handler = MyHTTPRequestHandler os.chdir(sample_dir) with socketserver.TCPServer(("", PORT), Handler) as httpd: print("Serving at port", PORT) httpd.serve_forever()
- 上面的代码在我们的
sample
目录中的端口8000
上启动一个 Python HTTP 服务器。 - 保存并退出文件。
- 允许执行
http_server.py
作为脚本。bashchmod +x http_server.py
- 创建一个 Service Worker 服务文件。bash
sudo nano /etc/systemd/system/pythonserver.service
- 将以下内容粘贴到服务文件中。确保将
User
和Group
值替换为你的实际值。此外,将WorkingDirectory
替换为实际的sample
目录路径,并将Execstart
替换为实际的http_server.py
路径。[Unit] Description= Daemon for Sample Demo Application After=network.target [Service] User=example_user Group=example_user WorkingDirectory= /example_user/sample ExecStart= /usr/bin/python3 /example_user/http_server.py [Install] WantedBy=multi-user.target
- 启动服务。bash
sudo systemctl start pythonserver
- 验证服务的状态。bash
sudo systemctl status pythonserver
- 输出将如下所示。
● pythonserver.service - Daemon for Sample Demo Application Loaded: loaded (/etc/systemd/system/pythonserver.service; disabled; preset: enabled) Active: active (running) since Fri 2024-04-05 10:29:31 UTC; 3s ago Main PID: 10181 (python3) Tasks: 1 (limit: 1011) Memory: 8.6M CPU: 43ms CGroup: /system.slice/pythonserver.service └─10181 /usr/bin/python3 /example_user/http_server.py
- 启用服务以便在系统启动时自动启动。bash
sudo systemctl enable pythonserver
使用 HTTPS 保护 Vultr 上的 Web 应用程序
出于安全原因,Service Worker 仅在 HTTPS 上下文中工作。这可以防止中间人攻击,并降低网络数据拦截和篡改的风险。
第一步是为你的 Web 应用程序配置反向代理。我们可以使用 Nginx 进行高效的请求处理和负载均衡。接下来,你需要从Let's Encrypt 请求免费的 SSL 证书以添加 HTTPS。执行此操作的步骤在我们的上一篇文章配置 Nginx 作为反向代理服务器和使用 Certbot 安装 SSL 证书中进行了描述。
应用 HTTPS 后,访问你的应用程序的 URL,如果一切正常,你将看到一个带有 Service Worker 作用域的警报。你还可以检查浏览器的开发者控制台以查看生命周期事件。第一次访问页面时,将打开缓存并安装 Service Worker。你可以刷新页面以查看 Service Worker 已激活,并且用户可以在离线状态下访问网页。要测试这一点,你可以关闭你的互联网连接并再次刷新页面。
结论
在本文中,我们了解了什么是 Service Worker 以及它们生命周期的不同阶段。我们还学习了如何创建一个带有 Service Worker 的 Web 应用程序,该应用程序为特定页面和资源添加离线功能。使用 Service Worker 可以通过允许用户即使在离线状态下也能访问内容来显著改善用户体验。
这是一篇由 Vultr 赞助的文章。Vultr 是全球最大的私有云计算平台。Vultr 受开发人员青睐,已为 185 个国家/地区的 150 多万客户提供了灵活、可扩展的全球云计算、云 GPU、裸机和云存储解决方案。详细了解Vultr