Github连接weatherPWAjavascript
weatherPWA demo:前端
Web Server
,更改端口便可使用(也能够本身搭建koa服务器)sync
功能的ServiceWoker监听器时会抽风,windows亲测无此类问题,因此尽可能使用window开发PWA程序!!push Notification
功能时要用到公钥
和私钥
,可用Postman进行推送测试var vapidKeys = {
publicKey:"BPwgIYTh9n2u8wpAf-_VzZ4dwaBY8UwfRjWZzcoX6RN7y5xD0RL9U4YDCdeoO3T8nJcWsQdvNirT11xJwPljAyk",
privateKey:"TIrMnK-r--TE7Tnwf-x4JfKwuFKz5tmQuDRWYmuwbhY"
}
function subscribeUserToPush(registration , publicKey){
var subscribeOptions = {
userVisibleOnly : true,
applicationServerKey : window.urlBase64ToUint8Array(publicKey)
};
return registration.pushManager.subscribe(subscribeOptions).then(function(pushSubscription){
console.log('pushscription' ,pushSubscription)
return pushSubscription;
})
}
// base64 => Unit8Array
// https://github.com/web-push-libs/web-push#using-vapid-key-for-applicationserverkey
window.urlBase64ToUint8Array = function (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;
}
function sendSubscriptionToServer(body, url) {
url = url || 'http://192.168.1.236:3000/subscription';
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.timeout = 60000;
xhr.onreadystatechange = function () {
var response = {};
if (xhr.readyState === 4 && xhr.status === 200) {
try {
response = JSON.parse(xhr.responseText);
console.log("user subscribed!");
alert("subscribed!");
sub_state = 1;
window.localStorage.setItem("subscription",1);
$('#subscription_btn').remove();
$('#add_btn').remove();
}
catch (e) {
response = xhr.responseText;
}
resolve(response);
}
else if (xhr.readyState === 4) {
resolve();
}
};
xhr.onabort = reject;
xhr.onerror = reject;
xhr.ontimeout = reject;
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(body);
});
}
function PUSH() {
if (sub_state === 0) {
if ('serviceWorker' in navigator && 'PushManager' in window) {
var publicKey = "BPwgIYTh9n2u8wpAf-_VzZ4dwaBY8UwfRjWZzcoX6RN7y5xD0RL9U4YDCdeoO3T8nJcWsQdvNirT11xJwPljAyk";
window.navigator.serviceWorker.ready.then(function (registration) {
//displayNotification();
// open the subscription function of the page
return subscribeUserToPush(registration, publicKey);
}).then(function (subscription) {
var body = {subscription: subscription};
// give every user a unique id in order to push notification
body.uniqueid = new Date().getTime();
console.log('uniqueid', body.uniqueid);
console.log(JSON.stringify(body))
// save the subscription info in the server (bedb used for saving)
return sendSubscriptionToServer(JSON.stringify(body));
}).then(function (res) {
console.log(res);
}).catch(function (err) {
console.log(err);
});
}else{
console.log('Push messaging is not supported.')
}
}else{
alert("you have already subscribed.")
}
}
复制代码
ServiceWorker
内部没法使用Localstorage
进行数据储存,由于ServiceWorker
是异步存储,因此若是须要将数据从ServiceWorker
传递到前端,须要使用IndexedDB
,建立新objectStore
来进行数据通信。在使用indexedDB
是须要注意更新的版本号,若是版本号不变,则没法添加新的store,也就没法给数据库添加新项目,只能更新已有数据。PortForwarding
来将localhost
的网页推到公网ip上测试,因此在后端的push
端口和sync
端口的ip地址就是当下手机和PC共有网络的ip地址,并不在localhost
。也就是说在ServiceWorker中对于端口ip地址的调用,必须将ip地址更改,才能正常使用后端端口。ajax
网络请求,须要使用fetch()
方法来进行网络请求fetch('http://192.168.1.137:3000/sync').then(function (response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: '+response.status);
return;
}
response.text().then(function (data) {
console.log("succeed access to sync interface");
var request = indexedDB.open("weatherPWA");
request.onupgradeneeded = function (event) {
var store = event.target.result.createObjectStore("real time", {keyPath:'id',autoIncrement: true });
store.createIndex('time','time',{unique:false});
}
request.onsuccess = function (event) {
console.log(data);
db = this.result;
var tx = db.transaction("real time",'readwrite');
store = tx.objectStore("real time");
var obj = {
id:0,
time:data
}
var req = store.put(obj);
req.onsuccess = function (event) {
//console.log(obj+" insert in DB successful");
};
req.onerror = function (event) {
console.log(obj+" insert in DB error",this.error);
}
}
request.onerror = function (event) {
console.log("opendb:", event);
};
console.log(data);
})
})
复制代码