什麼是 PWA

編者按
本文做者:吳昀珠(機智哥)
我的主頁:https://github.com/cleverboy32html

什麼是 PWA

先說一下全名,progressive web app: 漸進式網頁應用。這是谷歌推出的,我是這樣理解的:git

  • 咱們通常寫 web 應用,在 pc 上是沒有緩存的,打開頁面的時去請求數據。github

  • 第二個也沒有像 app 同樣的小圖標放在桌面,一點開就進入了應用,而是經過打開瀏覽器輸入網址,web

  • 第三個就是,不能像 app 同樣給用戶推送消息,像微博會跟你推送說有誰評論了你的微博之類的功能。chrome

而谷歌推出的 pwa,就是具備這些了這些特色, 使咱們的 web 應用,可以像一款 app 同樣使用。而且對比與 app, 它不用複雜的安裝,也不用下載更新包,刷新頁面就能夠了(注意到緩存的處理)。數據庫

那麼這些功能分別是怎麼實現的呢?

關於緩存json

其實這個就是 咱們平時作的 Session 啊、localStorage、CacheStorage 之類的。api

這裏用的就是 cacheStorage 緩存,它提供了一個ServiceWorker類型的工做者或window範圍能夠訪問的全部命名緩存的主目錄, 並維護字符串的映射名稱到相應的 Cache 對象。 主要方法包括: promise

這裏寫圖片描述
有了這些方法你能夠對你的緩存進行操做。目前還在草案狀態,僅火狐和谷歌瀏覽器支持此特性。

PWA是經過 ServiceWorker 訪問 cache ,因此須要註冊 ServiceWorker 工做者。在以前別忘記判斷瀏覽器是否支持。瀏覽器

if ('serviceWorker' in navigator) {
	navigator.serviceWorker.register(sw.js) // 註冊sw.js 文件中變成的服務對象,返回註冊成功的對象
	.then(function(swReg){
          swRegistration = swReg;
     }).catch(function(error) {
          console.error('Service Worker Error', error);
     });
}
複製代碼

這個 Service Worker 服務工做者就厲害了,它至關於瀏覽器和網絡之間的代理服務器,能夠攔截網絡請求,作一些你可能須要的處理(請求資源從緩存中獲取等)。

  • 它可以建立有效的離線體驗,攔截網絡請求,並根據網絡是否可用判斷是否使用緩存數據或者更新緩存數據。

  • 它們還容許訪問推送的通知和後臺的API。

關於 sw.js 中具體的緩存的代碼:

建立須要緩存的文件

'use strict'
let cacheName = 'pwa-demo-assets'; // 緩存名字
let imgCacheName = 'pwa-img';
let filesToCache;
filesToCache = [ // 所需緩存的文件
    '/',
    '/index.html',
    '/scripts/app.js',
    '/assets/imgs/48.png',
    '/assets/imgs/96.png',
    '/assets/imgs/192.png',
    '/dist/js/app.js',
    '/manifest.json'
];

self.addEventListener('install', function(e) {
    e.waitUntil(
	    // 安裝服務者時,對須要緩存的文件進行緩存
        caches.open(cacheName).then(function(cache) {
            return cache.addAll(filesToCache);
        })
    );
});


self.addEventListener('fetch', (e) => {
    // 判斷地址是否是須要實時去請求,是就繼續發送請求
    if (e.request.url.indexOf('/api/400/200') > -1) {
        e.respondWith(
            caches.open(imgCacheName).then(function(cache){
                 return fetch(e.request).then(function (response){
                    cache.put(e.request.url, response.clone()); // 每請求一次緩存更新一次新加載的圖片
                    return response;
                });
            })
        );
    } else {
        e.respondWith(
	        // 匹配到緩存資源,就從緩存中返回數據
            caches.match(e.request).then(function (response) {
                return response || fetch(e.request);
            })
        );
    }

});
複製代碼

這裏進而就引入到 pwa 的推送通知功能。這都是經過 ServiceWorker 去實現的。

基本原理是,你的客戶端要和推送服務進行綁定,會生成一個綁定後的推送服務 API 接口,服務端調用此接口,發送消息。同時,瀏覽器也要支持推送功能,在註冊 sw 時, 加上推送功能的判斷。

if ('serviceWorker' in navigator && 'PushManager' in window) {
	navigator.serviceWorker.register(sw.js)
	.then(function(swReg) {
        swRegistration = swReg;
    }).catch(function(error) {
        console.error('Service Worker Error', error);
        });
 } else {
     console.warn('Push messaging is not supported');
 }
複製代碼

PushManager 註冊好以後, 那麼要作的就是瀏覽器和服務器的綁定了。

這裏寫圖片描述
此圖是用戶訂閱某個應用程序的推送服務。 客戶端傳入應用程序服務器公鑰,向將生成端點的 webpush 服務器( 這是谷歌本身實現的一個推送功能的服務器)發出網絡請求,將生成的端點(一個推送服務)與應用程序公鑰關聯,並將端點返回給應用程序。瀏覽器會將此端點添加到 PushSubscription,經過 promise異步成功時,能夠將它的信息保存到你的數據庫。

這裏寫圖片描述
服務器發送推送的時候,請求相關接口,驗證成功後推送服務會發消息給客戶端。

最後關於桌面小圖標

這個能夠說是很是簡單了,就是一個 manifest.json 配置文件,而後在頁面引入此文件就行了

<!-- 加載清單 -->
<link rel="manifest" href="./manifest.json">
複製代碼

關於清單內容這裏簡單介紹一下:

{
    "short_name": "pwa",
    "name": "pwa - demo", // 應用名稱
    "icons": [ // 應用顯示圖標,根據容器大小適配
        {
            "src": "assets/imgs/48.png",
            "type": "image/png",
            "sizes": "48x48"
        },
        {
            "src": "assets/imgs/96.png",
            "type": "image/png",
            "sizes": "96x96"
        },
        {
            "src": "assets/imgs/192.png",
            "type": "image/png",
            "sizes": "192x192"
        }
    ],
    "background_color": "#2196F3", // 剛打開頁面時的背景
    "theme_color": "#2196F3", // 主題顏色
    "display": "standalone", //獨立顯示
    "start_url": "index.html?launcher=true" // 啓動的頁面
}
複製代碼

好了, 若是感興趣趕快上手吧。 能夠查看谷歌官方教程

這裏說一下坑的點, PWA應用須要在本地localhost:8080 上運行或者 https 協議下, 要保證你的頁面是安全頁面。

添加桌面時,確保你的谷歌瀏覽器能夠顯示彈出通知。

若是你要本身實現推送,本身服務器要有公鑰和私鑰的獲取, 這裏能夠經過 https://web-push-codelab.glitch.me 獲取, 用 chrome 的 webpush 推送。

這裏也能夠看一下個人 GitHub 項項目 ,官方也有不少例子。

相關文章
相關標籤/搜索