編者按
本文做者:吳昀珠(機智哥)
我的主頁:https://github.com/cleverboy32html
先說一下全名,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 項項目 ,官方也有不少例子。