更改推送管理器订阅中的应用程序服务器密钥
Changing application server key in push manager subscription
我使用 service worker 实现了网络推送通知。我使用特定的应用程序服务器密钥收集用户订阅。假设如果我们更改应用服务器密钥,那么当我们使用 "reg.pushManager.getSubscription()" 获取订阅时,我们将获得使用旧应用服务器密钥创建的旧订阅信息。如何处理这种情况?如何获取用户的新订阅?
使用reg.pushManager.getSubscription()
获取订阅并检查当前订阅是否使用新的应用程序服务器密钥。如果没有,则在现有订阅上调用 unsubscribe()
函数并重新订阅。
正确启动 service worker 并获得权限后,调用 navigator.serviceWorker.ready
以访问 *.pushManager
对象。
我们从这个对象调用另一个 promise 来获得我们真正关心的 pushSubscription
对象。
如果用户从未订阅过 pushSubscription
将是 null
否则我们从中获取密钥并检查它是否不同,如果是这种情况我们取消订阅用户并再次订阅他们。
var NEW_PUBLIC_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
Notification.requestPermission(function (result) {
if (permissionResult == 'granted'){
subscribeUser();
}
});
function subscribeUser() {
navigator.serviceWorker.ready
.then(registration => {
registration.pushManager.getSubscription()
.then(pushSubscription => {
if(!pushSubscription){
//the user was never subscribed
subscribe(registration);
}
else{
//check if user was subscribed with a different key
let json = pushSubscription.toJSON();
let public_key = json.keys.p256dh;
console.log(public_key);
if(public_key != NEW_PUBLIC_KEY){
pushSubscription.unsubscribe().then(successful => {
// You've successfully unsubscribed
subscribe(registration);
}).catch(e => {
// Unsubscription failed
})
}
}
});
})
}
function subscribe(registration){
registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(NEW_PUBLIC_KEY)
})
.then(pushSubscription => {
//successfully subscribed to push
//save it to your DB etc....
});
}
function urlBase64ToUint8Array(base64String) {
var padding = '='.repeat((4 - base64String.length % 4) % 4);
var base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
var rawData = window.atob(base64);
var outputArray = new Uint8Array(rawData.length);
for (var i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
就我而言,我通过清除缓存和 cookie 设法解决了这个问题
我使用 service worker 实现了网络推送通知。我使用特定的应用程序服务器密钥收集用户订阅。假设如果我们更改应用服务器密钥,那么当我们使用 "reg.pushManager.getSubscription()" 获取订阅时,我们将获得使用旧应用服务器密钥创建的旧订阅信息。如何处理这种情况?如何获取用户的新订阅?
使用reg.pushManager.getSubscription()
获取订阅并检查当前订阅是否使用新的应用程序服务器密钥。如果没有,则在现有订阅上调用 unsubscribe()
函数并重新订阅。
正确启动 service worker 并获得权限后,调用 navigator.serviceWorker.ready
以访问 *.pushManager
对象。
我们从这个对象调用另一个 promise 来获得我们真正关心的 pushSubscription
对象。
如果用户从未订阅过 pushSubscription
将是 null
否则我们从中获取密钥并检查它是否不同,如果是这种情况我们取消订阅用户并再次订阅他们。
var NEW_PUBLIC_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
Notification.requestPermission(function (result) {
if (permissionResult == 'granted'){
subscribeUser();
}
});
function subscribeUser() {
navigator.serviceWorker.ready
.then(registration => {
registration.pushManager.getSubscription()
.then(pushSubscription => {
if(!pushSubscription){
//the user was never subscribed
subscribe(registration);
}
else{
//check if user was subscribed with a different key
let json = pushSubscription.toJSON();
let public_key = json.keys.p256dh;
console.log(public_key);
if(public_key != NEW_PUBLIC_KEY){
pushSubscription.unsubscribe().then(successful => {
// You've successfully unsubscribed
subscribe(registration);
}).catch(e => {
// Unsubscription failed
})
}
}
});
})
}
function subscribe(registration){
registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(NEW_PUBLIC_KEY)
})
.then(pushSubscription => {
//successfully subscribed to push
//save it to your DB etc....
});
}
function urlBase64ToUint8Array(base64String) {
var padding = '='.repeat((4 - base64String.length % 4) % 4);
var base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
var rawData = window.atob(base64);
var outputArray = new Uint8Array(rawData.length);
for (var i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
就我而言,我通过清除缓存和 cookie 设法解决了这个问题