Linux development environment, Chrome debugging

Making links weatherPWA

weatherPWA demo:

  1. The server uses Chrome’s built-in appWeb Server, you can use it by changing the port (you can also build your own KOA server)
  2. Linux chrome is in usesyncThe ServiceWoker listener will leak. Windows does not have this problem, so try to use Windows to develop PWA programs!!
  3. usepush NotificationFunction is usedThe public keyandThe private key, Postman can be used for push testing
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)
        returnpushSubscription; })}// 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.")}}Copy the code
  1. inServiceWorkerInternal unusableLocalstorageFor data storage becauseServiceWorkerIs asynchronous storage, so if you need to move data fromServiceWorkerPass to the front end, need to useIndexedDBTo create a newobjectStoreFor data communication. In the use ofindexedDBIt is necessary to pay attention to the updated version number. If the version number remains unchanged, new store cannot be added to the database, so new items can only be updated to the existing data.
  2. When using mobile phones to test web pages, you need to pay special attention to setting the IP address of the back-end server. Because when you debug a web page on chrome, you need to use itPortForwardingtolocalhostThe web page is pushed to the public IP for testing, so the back endpushPort andsyncThe IP address of the port is the IP address of the network shared by the mobile phone and PClocalhost. That is to say, the IP address of the port must be changed in ServiceWorker calls so that the back-end port can be used properly.
  3. Not available in ServiceWorkerajaxNetwork request, requiredfetch()Method to make a network request
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); })})Copy the code