Progressive Web Apps
- Web 技术编写出一个网页应用
- App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能
- 本质上是 Web App
- 兼具 Web App 和 Native App 的优点
特点: 可靠、安全、粘性
安装 http-server
npm install –global http-server
用法
http-server [path] [options]
注意:默认情况下,缓存处于打开状态。添加-c-1为禁用缓存的选项。
http-server -c-1
默认访问地址:http://localhost:8080
安装 ngrok
简单应用示例
index.html main.css
添加 manifest.json 文件
定义应用的名称, 图标等信息
- 添加 Service Worker
网页已经关闭的情况下还可以运行, 用来实现页面的缓存和离线, 后台通知等等功能
1 | if(navigator.serviceWorker != null){ |
Service Worker 全局变量
self: 表示 Service Worker 作用域, 也是全局变量
caches: 表示缓存
skipWaiting: 表示强制当前处在 waiting 状态的脚本进入 activate 状态
clients: 表示 Service Worker 接管的页面
- navigator.serviceWorker.register(‘sw.js’) 注册安装 Service Worker
1 | // 注册完成安装时,抓取资源写入缓存 |
self.skipWaiting() 方法是为了在页面更新的过程当中, 新的 Service Worker 脚本能立即激活和生效
1 | self.addEventListener('activate', function(e) { |
调用 self.clients.claim() 取得页面的控制权, 这样之后打开页面都会使用版本更新的缓存
查看 Service Worker
DevTools 的 Application 标签可以看到 Service Worker
功能和特性
独立 worker 线程,独立于当前网页进程,有独立的 worker context
一旦被 install,永远存在,除非 uninstall
具备唤醒,待机功能(存在坑)
可编程拦截代理请求和返回,缓存文件,缓存的文件可以被网页进程获取(包括网络离线状态)
离线内容开发者可控
可以向客户端推送消息
不能直接操作Dom
处于完全考虑,必须 HTTPS 环境下工作
异步实现,通过 Promise
Lavas
基于 Vue 的 PWA (Progressive Web Apps) 完整解决方案
踩坑记录
navigator.onLine 只会在机器未连接到局域网或路由器时返回false,其他情况下均返回true
Fetch
Fetch 是基于promise,network error 时返回 rejected 的 promise,ftp 协议不支持 Fetch
默认情况下不包括请求中的任何cookie
fetch(‘/url’, { credentials: ‘include’ })
上传JSON时忘记设置
{'Content-Type': 'application/json'}
fetch(‘/url’, {
method: 'POST', body: JSON.stringify({text: 'bacon'}), headers: {'Content-Type': 'application/json'}}) .then(res => res.json()) .then(console.log)
字符串手动拼接一个复杂的查询参数
应该使用 URLSearchParams 类
获取返回值
fetch(‘./url’).then(res =>{
return res.json()
}).then(data=>{
console.log(data)
})
兼容性问题
由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
引入 Promise 的 polyfill: es6-promise
引入 fetch 探测库:fetch-detector
引入 fetch 的 polyfill: fetch-ie8
可选:如果你还使用了 jsonp,引入 fetch-jsonp
可选:开启 Babel 的 runtime 模式,现在就使用 async/await
- 不支持timeout,不支持 progress,特别是 fetch 在跨域问题上与传统跨域的处理方式的区别
let myHeaders = new Headers({
‘Access-Control-Allow-Origin’:’*’,
“Content-Type”:’text/plain’
})
fetch(url,{
method:’GET’,
headers:myHeaders,
mode:’cors’
}).then(res=>{
return res.text()
}).then(data=>{
console.log(data)
})
mode设置成:‘no-cors’ 请求时,reponse 响应中 type 显示为 opaque,则这时候该使用 jsonp 或者后端代理
- App Shell 模型、离线 UX 注意事项