PWA 开发总结(坑多)

Linux开发环境,Chrome调试

Github链接weatherPWA

weatherPWA demo:

  1. 服务器使用Chrome的内置app Web Server,更改端口即可使用(也可以自己搭建koa服务器)
  2. 使用linux的chrome浏览器在使用sync功能的ServiceWoker监听器时会抽风,windows亲测无此类问题,所以尽量使用window开发PWA程序!!
  3. 使用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.")
    }   
    
}
复制代码
  1. ServiceWorker内部无法使用Localstorage进行数据储存,因为ServiceWorker是异步存储,所以如果需要将数据从ServiceWorker传递到前端,需要使用IndexedDB,创建新objectStore来进行数据通讯。在使用indexedDB是需要注意更新的版本号,如果版本号不变,则无法添加新的store,也就无法给数据库添加新项目,只能更新已有数据。
  2. 在使用手机进行网页测试时,对于后端服务器的ip地址设置问题,需要格外注意。因为在手机chrome上调试网页时,需要使用PortForwarding来将localhost的网页推到公网ip上测试,所以在后端的push端口和sync端口的ip地址就是当下手机和PC共有网络的ip地址,并不在localhost。也就是说在ServiceWorker中对于端口ip地址的调用,必须将ip地址更改,才能正常使用后端端口。
  3. 在ServiceWorker中无法使用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);
      })
    })
复制代码

转载于:https://juejin.im/post/5cbf61abf265da035f6fd941

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值