如何立即通知你的用户,网站有新内容更新?

你有没有遇到过这样的场景:当你在浏览网页时,突然收到一个通知,告诉你有新的内容更新,或者有一条重要的消息通知你查看。

作为一枚前端开发,你可能会想,这不就是请求轮询吗?

没错,异步请求通过轮询的方式确实能实现类似的功能,但这不是我们今天要分享的主题 ~

是什么呢?

Service Worker

是的,通过 Service Worker 来实现“推送通知”的功能。Service Worker 是 Web API 的一部分,其功能非常强大。相信通过今天的内容,你肯定会有所收获。

那么现在,就让我们正式开始吧~

1. 初识 Service Worker

简单来说,Service Worker 是一种在浏览器背后默默工作的 JS 脚本,它可以在用户没有打开网页的情况下运行,为网页提供了各种强大的功能,比如离线缓存、后台同步等,当然还有我们今天要分享的——推送通知。

有些网站的推送通知做的相当不错,比如油管(YouTube)。当你关注了油管上的某个 UP 主,当 TA 更新视频后浏览器就会给你推送消息,这时候就算你没有打开浏览器,你也会收到通知。Windows 10 系统上在桌面右下角会弹出一个来自浏览器的消息通知框,通知的内容来自油管那位 UP 主的更新信息;Mac 系统上,在桌面右上角会有一条来自浏览器的通知,通知的内容与 Windows 上的信息一致。

你可能会问,为什么我们要使用 Service Worker 来实现推送通知呢?

原因很简单,因为它可以帮助我们更好地与用户进行交互,能提高用户的参与度,甚至在一定程度上可以提高用户的留存率。设想一下,如果你的网站有新的内容更新,你可以立即通过推送通知告诉你的用户。

这样的话,你的用户就不会错过重要通知了,而通知的内容恰好又戳到了用户的 G 点,那 TA 肯定会点一下消息框,然后瞬间就回到你的网站了。相较于用户首先打开浏览器然后点击书签访问到你的网站来说,这种类似于系统级别的消息通知能极大提高用户粘性。

所以,要不要考虑把 Service Worker 在自己网站上用起来呢?

下面,我们就来一步步实现这个功能。

2. Service Worker 基础

现在你已经对 Service Worker 有了一个基本的了解,接下来我们看一下它的基础知识。

首先你要明白 Service Worker 是如何实现推送通知的。其实它的工作原理也不复杂,当用户访问网页时,Service Worker 就会被安装到用户的设备上。当服务器有新的信息需要传递给用户时,服务器就会发送一个推送事件到 Service Worker。然后,Service Worker 就会接收这个事件推送,并根据这个事件显示给用户一个通知。

这就是 Service Worker 实现推送通知的基本原理,是不是挺简单的?

接下来让我们动手实践一下吧 ~

3. 注册 Service Worker

第一步,我们需要注册一个 Service Worker。你可能会问,“注册 Service Worker”是什么意思呢?

其实,这是要跟浏览器说:

“Hi,我要在我的网站上用 Service Worker 哦~”

要怎么注册 Service Worker 呢?很简单,只需要几行代码。首先,你需要检查一下浏览器是不是支持 Service Worker。检查方式也不难,通过浏览器的 navigator 对象上的 serviceWorker 属性来判断即可。如果 navigator.serviceWorker 存在,则表示浏览器支持 Service Worker。

具体代码如下:

if ("serviceWorker" in navigator) {
  window.addEventListener("load"function () {
    navigator.serviceWorker.register("/sw.js").then(
      function (registration{
        console.log("Service Worker 注册成功,作用域是:", registration.scope);
      },
      function (err{
        console.log("Service Worker 注册失败,错误是:", err);
      }
    );
  });
}

这段代码中有个地方需要注意,在 register 方法中需要提供 Service Worker 的脚本路径,这里放在了网站根目录。比如,你用的是 Next.js,那么 sw.js 文件就应该放在 public 目录下面。

navigator.serviceWorker.register 方法返回一个 Promise,这个 Promise 在 Service Worker 注册成功时会解析为一个 registration 对象,这个对象包含了关于 Service Worker 的一些信息,比如它的作用域。如果 Service Worker 注册失败,Promise 会被拒绝,并且错误信息会被捕获并打印出来。

我们看一下在浏览器中注册之后的效果:

如何立即通知你的用户,网站有新内容更新?

注册 Service Worker

是不是注册 Service Worker 很简单?

注册完,接下来就是订阅了。

4. Service Worker 订阅推送

什么是“订阅推送”呢?简单来说,订阅推送就是告诉服务器:

“Hey,有新的消息要告诉我哦~”

这样,当服务器有新的内容时,它就会把这些内容推送给你。

那么,我们如何使用 Service Worker 订阅推送呢?其实,这个过程也非常简单,几个步骤就能搞定。

首先要做的:获取用户许可。为什么要征得用户同意才行呢?因为推送通知是一种可以打扰到用户的行为,所以我们需要获取用户的许可才行。

至于请求用户许可的方法也很简单,用 Notification.requestPermission 方法来征得用户同意即可。调用这个方法后,浏览器会弹出一个对话框,询问用户是否允许接收通知。如果用户同意,这个方法就会返回一个解析为 'granted' 的 Promise。

然后,我们还需要生成一个订阅对象。可以通过 registration.pushManager.subscribe 方法来生成一个订阅对象。这个方法需要一个参数,这个参数是一个包含 userVisibleOnlyapplicationServerKey 属性的对象。userVisibleOnly 属性表示每个推送消息都必须对用户可见,applicationServerKey 属性是服务器的公钥,用于加密推送消息。

最后,我们需要把这个订阅对象发送给服务器。可以使用 fetch 方法来发送一个 POST 请求到服务器,请求的主体就是我们的订阅对象。

参考代码如下:

Notification.requestPermission().then(function (permission{
  if (permission === "granted") {
    navigator.serviceWorker.ready.then(function (registration{
      registration.pushManager
        .subscribe({
          userVisibleOnlytrue,
          // PUBLIC_KEY 是 VAPID 公钥,VAPID 公钥和秘钥是配对的,需要在你自己的服务器上生成 VAPID 公钥和私钥。
          // 可以在 https://web-push-codelab.glitch.me/ 中生成用公钥和秘钥以做测试用。
          applicationServerKey: urlBase64ToUint8Array("YOUR_PUBLIC_KEY"),
        })
        .then(function (subscription{
          fetch("/subscribe", {
            method"POST",
            headers: {
              "Content-Type""application/json",
            },
            bodyJSON.stringify(subscription),
          });
        });
    });
  }
});

在这段代码中,我们首先请求用户的许可。如果用户同意接收通知,我们就等待 Service Worker 准备好,然后生成一个订阅对象,并把这个订阅对象发送给服务器。

之后服务器可以返回一个消息告诉浏览器是否订阅成功,比如我们在 Next.js 中模拟一下:

// pages/api/subscribe.js
import type { NextApiRequest, NextApiResponse } from "next/types";
export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<{ message: string }>
) {
  if (req.method === "POST") {
    // 在这里处理订阅对象
    const subscription = req.body;
    // 保存订阅对象到数据库或其他地方
    // ...
    res.status(200).json({ message"订阅成功" });
  } else {
    res.status(405).json({ message"只接受 POST 请求" });
  }
}

 

服务器收到订阅对象后,返回了一个对象表示订阅成功。

如何立即通知你的用户,网站有新内容更新?

Service Worker 订阅

这样,当服务器有新的消息时就能直接通知到用户了。

如果你想测试一下消息推送功能该怎么办呢?这个也很简单。

你可以在 Service Worker 中模拟一下从服务端发送消息:

// Service Worker: /public/sw.js
self.addEventListener("push"function (event) {
  const title = "新消息:模拟服务端发送的消息!";
  const options = {
    body: event.data.text(),
  };
  event.waitUntil(self.registration.showNotification(title, options));
});

之后,你可以使用浏览器的开发者工具来模拟推送事件。在浏览器的开发者工具中,你可以选择“应用”选项卡下的 “Service Worker”菜单,然后点击 "推送" 按钮来模拟一个推送事件。

如何立即通知你的用户,网站有新内容更新?

浏览器模拟 Service Worker 推送事件

因为录屏录不到系统通知,只能手机录像为大家展示了,凑活看吧…… 意思你肯定明白的 ~

如何立即通知你的用户,网站有新内容更新?

Service Worker 消息通知

5. 交互通知

目前为止,我们已经实现了“推送通知”的功能,但是只有通知是不够的。我们还需要让用户能够与这个通知进行交互。比如,当用户看到这个通知后可能会下意识去点一下,那么,我们就可以通过用户的这个点击动作,把用户引导到我们的网站上。

具体应该怎么实现呢?

其实也不难,我们只需要在 Service Worker 中添加一个监听器就可以了。这个事件监听器会监听 'notificationclick' 事件,当用户点击通知时,这个事件就会被触发。

self.addEventListener('notificationclick'function(event{
  event.notification.close(); // 关闭通知
  event.waitUntil(
    clients.openWindow('https://www.yourwebsite.com'// 打开你的网站
  );
});

这段代码会在用户点击通知时关闭通知,并打开你的网站。

​是不是很简单?这里就不放截屏了。

6. 最佳实践和注意事项

至此,Service Worker 推送通知就已经实现了。不过这一功能需要后端支持,如果你对后端开发有一些经验,那就再好不过了。

但是,还有一些需要注意的事项。

首先,你的网站必须是通过 HTTPS 访问的,因为 Service Worker 只能在 HTTPS 网站上生效。这主要是基于安全的考虑。

再就是 Service Worker 有它自己的生命周期,它会在安装、激活和终止等阶段执行不同的任务。所以,你要理解、掌握它的生命周期。鉴于篇幅原因,这部分内容没有涉及。不过不要担心,这部分内容会后面和大家分享。

最后一点就是用户体验的问题了。虽然其推送通知的能力非常强,但是如果频繁给用户推送消息,用户得烦死了~ 所以,你要尽可能保证你推送的通知是有价值的,且不能过于频繁。还有一点,你应该、也必须提供一个简单的方式让用户能取消订阅。这部分内容我们也会在后面和大家分享,你可以先自己了解一下这方面的知识。

7. 小结

在今天的分享中,我们一起学习了 Service Worker 的注册、订阅推送,再到实现交互通知,最后我们还总结了一些最佳实践和注意事项。

希望通过今天的分享,你能从中学到一些关于 Service Worker 的知识。如果你有什么问题可以在下面留言,我们一起学习,文中如有错误也请不吝指正。

那么,今天的内容就到这里了,感谢你的阅读,我们下期再见 🙂

免责说明

本站资源部分来自网友投稿,如有侵犯你的权益请联系管理员或给邮箱发送邮件PubwinSoft@foxmail.com 我们会第一时间进行审核删除。
站内资源为网友个人学习或测试研究使用,未经原版权作者许可,禁止用于任何商业途径!请在下载24小时内删除!


如果遇到评论下载的文章,评论后刷新页面点击对应的蓝字按钮即可跳转到下载页面
本站资源少部分采用7z压缩,为防止有人压缩软件不支持7z格式,7z解压,建议下载7-zip,zip、rar解压,建议下载WinRAR

给TA打赏
共{{data.count}}人
人已打赏
ClaudeCode开源推荐其它源码

Claude重磅更新Claude 100k如何申请开通?

2023-6-5 11:34:25

WordPress插件WordPress教程建站教程

如何将 WordPress与 ChatGPT 集成?

2023-6-13 9:00:22

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
有新私信 私信列表
搜索