推荐答案
// www.javascriptcn.com code example
// 1. 注册 Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service Worker 注册成功:', registration);
// 2. 请求用户授权
return registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array('YOUR_PUBLIC_VAPID_KEY')
});
})
.then(function(subscription) {
console.log('用户已授权:', subscription);
// 3. 将 subscription 发送到服务器
fetch('/api/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: {
'Content-Type': 'application/json'
}
});
})
.catch(function(error) {
console.error('Service Worker 注册或推送订阅失败:', error);
});
}
// 4. 在 Service Worker 中监听推送事件
self.addEventListener('push', function(event) {
const data = event.data.json();
const title = data.title || '新消息';
const options = {
body: data.body || '您有一条新消息',
icon: '/icon.png',
badge: '/badge.png'
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// 5. 将 VAPID 公钥转换为 Uint8Array
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}本题详细解读
1. 注册 Service Worker
首先,我们需要注册一个 Service Worker。Service Worker 是一个在后台运行的脚本,它可以拦截网络请求、缓存资源以及处理推送通知。
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service Worker 注册成功:', registration);
});
}2. 请求用户授权
在 Service Worker 注册成功后,我们需要请求用户授权以接收推送通知。使用 pushManager.subscribe 方法可以订阅推送服务,并生成一个唯一的 subscription 对象。
registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array('YOUR_PUBLIC_VAPID_KEY')
});3. 将 subscription 发送到服务器
用户授权后,我们需要将 subscription 对象发送到服务器,以便服务器能够通过这个 subscription 向用户发送推送通知。
fetch('/api/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: {
'Content-Type': 'application/json'
}
});4. 在 Service Worker 中监听推送事件
当服务器发送推送通知时,Service Worker 会接收到 push 事件。我们可以在这个事件中处理推送通知,并显示给用户。
// www.javascriptcn.com code example
self.addEventListener('push', function(event) {
const data = event.data.json();
const title = data.title || '新消息';
const options = {
body: data.body || '您有一条新消息',
icon: '/icon.png',
badge: '/badge.png'
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});5. 将 VAPID 公钥转换为 Uint8Array
VAPID(Voluntary Application Server Identification)是一种用于推送通知的身份验证机制。我们需要将 VAPID 公钥从 Base64 格式转换为 Uint8Array,以便在 pushManager.subscribe 中使用。
// www.javascriptcn.com code example
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}