PWA(Progressive Web App)是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生功能,比如通知推送。在移动端利用标准化框架,让网页应用呈现和原生应用相似的体验。
pwa mdn
manifest_mdn
web程序应用清单
Web应用程序清单在一个JSON文本文件中提供有关应用程序的信息(如名称,作者,图标和描述)。manifest 的目的是将Web应用程序安装到设备的主屏幕,为用户提供更快的访问和更丰富的体验。
新建 manifest.json文件,
引入,必须在https 或者 http://localhost 运行。 个人是vscodelive Serve
插件
常见配置
name:指定应用名称
short_name: 应用短名称,主屏显示
start_url:用户启动程序加载的url
icons:各个平台icon
background_color:用户指定的背景颜色
theme_color:主题色
display: app显示方式
MDN 范例
{
"name":"测试项目--appp",
"short_name":"测试1",
"start_url":"/index.html",
"icons":[
{
"src":"images/1.jpg",
"size":"144x144",
"type":"images/jpg"
}
],
"background_color":"skyblue",
"theme_color":"yellow",
"display":"standalone"
}
前提条件
了解 worker
worker mdn
运行者 Worker 接口是Web Workers API 的一部分,代表一个后台任务,它容易被创建并向创建者发回消息。创建一个运行者只要简单的调用Worker()构造函数,指定一个脚本,在工作线程中执行。临时
let myWorker = new Worker("worker.js");
myworker.addEventListener('message',e=>{ console.log(e) }),
// worker.js
self.postMessage({data})
简单的注册监听
那正主来了 Service workor
service worker
注册步骤
<script>
window.addEventListener('load',()=>{
if('serviceWorker' in navigator){
navigator.serviceWorker.register('./sw.js').then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
}
})
</script>
生命周期
install 会在 service worker 注册成功后触发,主要用于缓存资源
activate 事件会在service worker激活后触发,一般用于删除旧的资源
fetch 发送请求的时候触发
self.addEventListener('install',event=>{
console.log('install',event)
// service worker 跳过等待 直接进入activate
event.waitUntil(self.skipWaiting())
})
self.addEventListener('activate',event=>{
console.log('activate',event)
// 表示service worker激活后,立即获取控制器
event.waitUntil( self.clients.claim())
})
self.addEventListener('fetch',event=>{
console.log('fetch',event)
})
关键是 返回的 res为数据流
fetch mdn
fetch('./data.json').then(res=>{
console.log(res) // 流
return res.json()
}).then(res=>{
console.log(res)
})
cache storage
CacheStorage 接口表示 Cache 对象的存储。它提供了一个 ServiceWorker 、其它类型worker或者 window 范围内可以访问到的所有命名cache的主目录(它并不是一定要和service workers一起使用,即使它是在service workers规范中定义的),并维护一份字符串名称到相应 Cache 对象的映射。
常见方法
CacheStorage.match()
检查给定的 Request 是否是 CacheStorage 对象跟踪的任何 Cache 对象的键,并返回一个resolve为该匹配的 Promise .
CacheStorage.has()
如果存在与 cacheName 匹配的 Cache 对象,则返回一个resolve为true的 Promise .
CacheStorage.open()
返回一个 Promise ,resolve为匹配 cacheName (如果不存在则创建一个新的cache)的 Cache 对象
CacheStorage.delete()
查找匹配 cacheName 的 Cache 对象,如果找到,则删除 Cache 对象并返回一个resolve为true的 Promise 。如果没有找到 Cache 对象,则返回 false.
CacheStorage.keys()
返回一个 Promise ,它将使用一个包含与 CacheStorage 追踪的所有命名 Cache 对象对应字符串的数组来resolve. 使用该方法迭代所有 Cache 对象的列表。
cache mdn
Cache.match
(request, options)
返回一个 Promise对象,resolve的结果是跟 Cache 对象匹配的第一个已经缓存的请求。
Cache.matchAll(request, options)
返回一个Promise 对象,resolve的结果是跟Cache对象匹配的所有请求组成的数组。
Cache.add
(request)
抓取这个URL, 检索并把返回的response对象添加到给定的Cache对象.这在功能上等同于调用 fetch(), 然后使用 Cache.put() 将response添加到cache中.
Cache.addAll
(requests)
抓取一个URL数组,检索并把返回的response对象添加到给定的Cache对象。
Cache.put
(request, response)
同时抓取一个请求及其响应,并将其添加到给定的cache。
Cache.delete
(request, options)
搜索key值为request的Cache 条目。如果找到,则删除该Cache 条目,并且返回一个resolve为true的Promise对象;如果未找到,则返回一个resolve为false的Promise对象。
Cache.keys
(request, options)
返回一个Promise对象,resolve的结果是Cache对象key值组成的数组。
简易
const CACHE_NAME = 'cache_v2'
// 加载缓存资源
self.addEventListener('install',async event=>{
const cache = await caches.open(CACHE_NAME)
await cache.addAll([
'/',
'/manifest.json',
'/images/1.jpg'
])
console.log('install',event)
// service worker 跳过等待 直接进入activate
await self.skipWaiting()
})
// 主要是清楚缓存
self.addEventListener('activate',async event=>{
console.log('activate',event)
const keys = await caches.keys()
keys.forEach(key => {
if(key !== CACHE_NAME){
caches.delete(key)
}
})
// 表示service worker激活后,立即获取控制器
await self.clients.claim()
})
// 如果数据请求成功就响应成功数据,如果失败,从缓存中取
self.addEventListener('fetch',event=>{
const req = event.request;
// 给浏览器响应
event.respondWith(netWorkFirst(req)) // 是否网络优先情况而定
})
// 网络优先
async function netWorkFirst(req){
try {
let fresh = await fetch(req)
return fresh
} catch (e) {
// 缓存取
const cache = await caches.open(CACHE_NAME)
const cached = await cache.match(req)
return cached
}
}
通知接口用于向用户配置和显示桌面通知。
noticcation mdn
浏览器默认权限
Notification.requestPermission() 用于当前页面向用户申请显示通知的权限。
if(Notification.permission === 'default'){ // 默认时去请求权限
Notification.requestPermission()
}
if(!navigator.onLine){
new Notification('提示', { body: '你当前没有网络'})
}
window.addEventListener('online',()=>{
new Notification('提示', { body : '你已经连上网络'})
})