在工作中遇到这样一个需求,要在web上完成将网页制作成快捷方式保存到桌面,可以通过桌面的快捷方式直接打开该网页。问题困扰了我许久(主要是不了解还有这项技术?偶然在网上看见这项技术的名称-PWA(Progressive Web App))。本文详解如何完成这个功能
什么是PWA?
效果展示
如何实现这个功能?
目录结构
- icon.png ----图标,下载时以及到桌面/chrome:apps中展示的图标
- index.html ----html文件
- mainfest.json ----json文件,通过这个json向浏览器暴露名称、icon以及URL等,供浏览器使用
- service-work.js ----是一个可编程的 Web Worker,它就像一个位于浏览器与网络之间的客户端代理,可以拦截、处理、响应流经的 HTTP 请求
- sw.js ----一个js文件,主要吧处理了下载功能,也可将其放入html中
icon.png
- 一个图标文件,建议大小128x128及以上
index.html
- 在index.html中引入了mainfest.json文件
<link rel="manifest" href="mainfest.json">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入json文件 -->
<link rel="manifest" href="mainfest.json">
</head>
<body>
<script>
// 检测浏览器是否支持SW
if (navigator.serviceWorker != null) {
navigator.serviceWorker.register('sw.js')
.then(function (registartion) {
console.log('支持sw:', registartion.scope)
})
} else {
console.log('不支持sw:')
}
navigator.serviceWorker.register('sw.js').then(function () {
console.log('serviceWorker registered')
}).catch(function (e) {
console.log("serviceWorker Error",e);
})
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
window.download = function (acceptedCallbackFunction) {
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
if (acceptedCallbackFunction) {
acceptedCallbackFunction();
}
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
};
});
</script>
</body>
</html>
mainfest.json
- 包含了背景、图标、描述、url等信息,
- 各属性详解pwa-mainfest
{
"background_color": "purple",
"display": "fullscreen",
"icons": [{
"src": "icon.png",
"sizes": "256x256",
"type": "image/png"
}],
"name": "Strange elimination: online elimination",
"short_name": "Strange elimination",
"start_url": "https://localhost:5555/index.html?campaignid=webapp"
}
service-work.js
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
workbox.core.clientsClaim();
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/index.html"), {
blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/],
});
sw.js
importScripts("service-worker.js");
self.addEventListener('install', (e) => {
console.log('sw install');
});
self.addEventListener('fetch', (e) => {});