「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
介绍通知 API 前端对用户的通知一般局限于页面之内,比如 alert,confirm。或者 javascript 控制一个弹窗提醒用户。有些场景需要在页面之外通知用户,也就是当用户页签不在本页面,或者浏览器已经被收起来的情况。
<script>
// default granted denied
console.log(Notification.permission)
</script>
首先判断一下是否获取接收通知的权限,上面代码用于检查当前页面是否有接收消息。对于Notification.permission 有 3 种取值
,
- defulat
- granted
- denied
当输出为denied 表示不允许接收该网页的通知,所以需要更改设定
- 在浏览器右上角更多菜单中选择"设置"
- 在右侧菜单中选择"隐私设置与安全性"
- 然后在左侧页面中选择"网站设置"
- 在"网站设置"页面中,下拉至"通知",选择"通知"
- 在"通知"页面中,将要接收通知页面添加到"允许发送通知"列表即可
<script>
// default granted denied
// console.log(Notification.permission)
if (Notification.permission === "granted") {
console.log("we have permission")
} else {
Notification.requestPermission().then(permission => {
console.log(permission)
})
}
</script>
function showNotification() {
const notification = new Notification("message from my site", {
body: "modern JS is coming soon."
})
}
接下来我们来实现比较完整的例子,首先通过我们先实现客户端代码,
addEventListener('load', async () => {
let sw = await navigator.serviceWorker.register('./sw.js');
console.log(sw);
});
async function subscribe(){
let sw = await navigator.serviceWorker.ready;
let push = await sw.pushManager.subscribe({
userVisibleOnly:true,
applicationServerKey:'TODO'
})
}
- 监听加载页面事件
load回调函数为异步回调函数中注册一个 serviceWork - 那么什么又是 serviceWork, serviceWork 是web 应用和远端服务中间的可编程的代理,有了 serviceWork 我们就可以对网络请求进行更多的控制
- 当 serviceWork 准备好了,就可以订阅服务端消息,这里需要一个应用
applicationServerKey不过接下来我们需要在服务端生成一下,
例如,serviceWork 可以控制对网站 HTML 请求的缓存行为,并将其与对网站图片的请求区别对待。服务工作者还使你能够处理推送信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button onclick="subscribe()">Subscribe</button>
<script>
addEventListener('load', async () => {
let sw = await navigator.serviceWorker.register('./sw.js');
console.log(sw);
});
async function subscribe(){
let sw = await navigator.serviceWorker.ready;
let push = await sw.pushManager.subscribe({
userVisibleOnly:true,
applicationServerKey:'TODO'
})
}
</script>
</body>
</html>
服务器端
在服务端需要安装 web-push 库,然后将其引用。首先我们调用 generateVAPIDKeys API 来生成 API IDKey
var push = require('web-push');
// console.log(push)
var vapiKeys = push.generateVAPIDKeys()
console.log(vapiKeys)
输出的publicKey 和privateKey 如下,现在我们就可以
{ publicKey: 'BC0IMqzFaJ3hFWPfNC0HrEQmkDTkUO6vxyboEoedg_NRINZJ8nneeg-RWANIgRTM5IHGkmi_lGLmrOz8uw5AFPE',
privateKey: 'ZtomiE0Kv21A2TIJNAvrlufDKiks1241Ezv5iOcJaVU' }