赞
踩
总结起来,网站配置PWA简单步骤为:
这个是我按照本文做的Demo,可以参考一下:https://lx164.netlify.app/ ,如果你的是Vue项目原理也是一样的。
开始之前建议先检查一下你的环境是否支持,支持PWA的浏览器请看这里:https://caniuse.com/?search=pwa
最新内容请以原文为准: https://www.cnblogs.com/LiangSenCheng/p/16702710.html
manifest.js 是用来定义名称、icon等信息的;
{ "name": "完整名称", // 用于安装横幅、启动画面显示 "short_name": "名称缩写", // 不为空时,桌面icon的名称优先为short_name "theme_color": "#f85758", // 主题色 "background_color": "#f85758", // 背景色 "display": "fullscreen", // 启动过渡动画, standalone或fullscreen "scope": "/", "start_url": "/", //启动页面,如果首页是https://www.abc.com/,则直接用“/”即可。 "icons": [ { "src": "logo72x72.png", "type": "image/png", "sizes": "72x72" }, { "src": "logo96x96.png", "type": "image/png", "sizes": "96x96" }, { "src": "logo144x144.png", "type": "image/png", "sizes": "144x144" } ] }
完整名称,用于安装横幅、启动画面显示
名称缩写,用于显示桌面Icon名称;不为空时,桌面icon的名称优先为short_name
主题色,指定 PWA 的主题颜色;通过该属性来控制浏览器 UI 的颜色。比如 PWA 启动画面上状态栏、内容页中状态栏、地址栏的颜色,会被 theme_color 所影响。
注:在指定了 theme_color 的值之后,地址栏依然呈白色。针对这种情况,可以在页面 HTML 里设置 name 为 theme-color 的 meta 标签,例如:,这个标签的色值会覆盖 manifest.json 里设置的 theme_color;
背景色,用来指定启动画面的背景颜色。
作用域,通过 scope 属性去限定作用域,超出范围的部分会以浏览器的方式显示。
如果没有在 manifest 中设置 scope,则默认的作用域为 manifest.json 所在文件夹;
scope 可以设置为 …/ 或者更高层级的路径来扩大PWA的作用域;
start_url 必须在作用域范围内;
如果 start_url 为相对地址,其根路径受 scope 所影响;
如果 start_url 为绝对地址(以 / 开头),则该地址将永远以 / 作为根地址;
start_url
启动页面,如果首页是https://www.abc.com/,则直接用“/”即可。
不同尺寸的icon,一般这个三个尺寸的都要,否则浏览器会出现警告: 72x72、96x96、144x144。
注意:三种尺寸的图片最好是保证图片的真实尺寸是72x72、96x96、144x144, 否则浏览器出现的警告可能会导致无法正常触发地址栏的install按钮。
可选值有:
fullscreen
: 应用的显示界面将占满整个屏幕standalone
: 浏览器相关UI(如导航栏、工具栏等)将会被隐藏minimal-ui
:显示形式与standalone类似,浏览器相关UI会最小化为一个按钮,不同浏览器在实现上略有不同移动端效果如下:
注:1. 在移动端如果要自动显示 “添加到桌面” 的弹窗,则display的值必须为:
fullscreen
或standalone
;2. 在windows桌面fullscreen和standalone的样式差不多,在移动端就有区别了;
浏览器识别后的内容类似下图,直接拿语雀的来举例:
// cache名, 在控制台Application的CaChe下可以看到 const cacheName = "penueling"; // cache文件 const cacheFiles = ["/", "/index.html", "/manifest.json"]; /** * 安装 Service Worker * install事件是 Service Worker 执行的第一个事件,同一个 Service Worker 只会调用一次 * 即使 Service Worker 脚本文件只有一个字节不同,浏览器也将视为一个新的 Service Worker */ self.addEventListener("install", e => { e.waitUntil( caches.open(cacheName).then(cache => { return cache.addAll(cacheFiles); }), ); }); /** * 激活 Service Worker * Service Worker 安装成功之后,会触发activate事件 * 在这个阶段我们一般做一些清理旧缓存相关的工作 */ self.addEventListener("activate", (e) => { // e.waitUntil(caches.delete(cacheName)); e.waitUntil( caches .keys() .then((keys) => { return Promise.all( keys.map((key) => { // 清理缓存 if (cacheName !== key) { return caches.delete(key); } }) ); }) .then(() => { console.log("cache deleted"); }) ); }); self.addEventListener("fetch", event => { event.respondWith( caches .open(cacheName) .then(cache => cache.match(event.request, { ignoreSearch: true })) .then(response => { return response || fetch(event.request); }), ); });
注:
self
: 这是 Service Worker 中特有的全局对象,类似与主线程中的window对象。
event.waitUntil
: 该函数接受一个Promise对象,它告诉 Service Worker,内部的Promise对象没有resolve之前,缓存工作就还没有完成,安装阶段也就没有完成,并且不应该转移到下一个阶段。
caches
: CacheStroge对象,它用来控制缓存相关的工作,caches对象的很多方法都是异步的,会返回一个Promise对象,更多详细的API可以参考这里(参考资料 6)。
缓存会保存在cacheName选项下:
最后一步是在index.html引入即可。
<head> // 引入manifest.json <link rel="manifest" href="/manifest.json" /> <script> // serviceWorker // 检查serviceWorker属性是否可用 if ("serviceWorker" in navigator) { window.addEventListener("load", function () { navigator.serviceWorker .register("./serviceWorker.js") .then(res => console.log("service worker registered")) .catch(err => console.log("service worker not registered", err)); }) } </script> </head>
如果serviceWorker.js是注册在域名的根目录下即 /
,这意味着我们可以在serviceWorker.js的fetch事件里,捕获到域名下所有的网络请求。换句话说,如果serviceWorker.js文件路径是/module/serviceWorker.js
,那么就只能在脚本里处理以/module
为开头的网络请求,比如 /module/app.js
按照上述的步骤配置好,在浏览器运行后,即可点击浏览器地址栏的安装按钮来触发安装弹窗。也可以通过点击Button来主动触发安装弹窗。
<script> var deferredPrompt = null; // 判断用户是否安装此应用:beforeinstallprompt,如果用户已经安装过了,那么该事件不会再次触发 // 需要卸载,然后重新打开浏览器才能再次触发 window.addEventListener("beforeinstallprompt", e => { e.preventDefault(); deferredPrompt = e; }); // 安装完成后触发,即点击安装弹窗中的“安装”后被触发 window.addEventListener("appinstalled", () => { deferredPrompt = null; }); function addToDesktop() { // 调用prompt()方法触发安装弹窗 deferredPrompt.prompt(); deferredPrompt = null; } </script> <button onclick="addToDesktop()">点击安装</button>
本地调试是,使用 localhost访问可以看到效果,如 vue 项目的本地调试地址为:localhost:8080
,那么直接访问localhost:8080即可;
注意:使用 127.0.0.1 访问是没有效果的,或者是 host
127.0.0.1 www.abc.com
访问也是没有效果的。换句话来说就是,用域名或者IP访问,需要是HTTPS
才行;
通过HTTPS访问,等待浏览器加载完页面,可以看到两个地方的入口;
manifest.json
和 serviceWorker.js
文件放在网站的根目录
,否则会出现作用域的问题;self.addEventListener('fetch', (e) => {})
即可;Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。