PWA
Progressive Web App 渐进式网络应用程序,简单来说,就是你可以通过一些浏览器接口,保存对应的资源,然后浏览器如果断网了,依然可以获取到保存的资源。跟上古的缓存差不多,但是这是已经被各大浏览器支持的特性,目前 Google 大力推进中。
本文项目
我们的项目就是我之前说的自己那个网站:only-u.site,这个是我自己用着玩的,然后挂在 Coding 上。这几天,貌似 Coding 抽风了,老是来回的抽风,我实在是受不了了,干脆挂在自己服务器用吧,不然我日常都没法用了,所以便有了如下的流程。
- 申请证书
- Express 部署网站
- 挂上 https 证书
- 补充 PWA 对应的资源
申请证书
由于本人域名买自阿里云,site 后缀的也便宜,就在阿里找 https 证书,放心,我穷,必然是免费版(有需求就上付费版,我是个人的,所以免费省点钱)。
阿里也是脏,免费的藏得很深。
这里是找不到免费证书的。
按图点击,否则还是看不到免费。
OK,露脸了。
购买,然后补全资料等审核,大概几分钟就好了。
PS:遇到选项就默认可以。
最后下载解压,你会得到两个文件,我们下面用到。
Express 部署 https 服务
Express 部署不多说,网上一大堆详细介绍,https 相关已经加上注释,代码如下(省略私密):
const path = require('path')
const express = require("express")
const https = require('https') // 没错,不是 http
const fs = require('fs')
const app = express()
const port = 443 // https 端口
const host = '110.110.110.110'
// 根据你具体项目结构设置路径,我路径是 index.html 在上层,所以这样设置
app.use(express.static(path.resolve(__dirname, '..')))
// 证书配置,这里就是那两个文件了
const privateKey = fs.readFileSync(__dirname + '/*.key')
const certificate = fs.readFileSync(__dirname + '/*.pem')
const credentials = { key: privateKey, cert: certificate }
// 根路径
app.get('/', (req, res) => {
const fileName = 'index.html'
fs.readFile(filePath, function (err, data) {
if (err) res.end("<h1>500</h1>服务器内部错误!")
else {
res.writeHead(200, { 'content-type': contentType })
res.end(data.toString())
}
})
})
// 启动服务
// 这个是 http
app.listen(80, host, err => {
if (err) console.log(err)
else console.log(`run in https://${host}:${port}`)
})
// 这个是 https
https.createServer(credentials, app).listen(port, host, err => {
if (err) console.log(err)
else console.log(`run in https://${host}:${port}`)
})
这样我们的页面就可以访问到了。如下:
设置 PWA
这里一样,关键步骤看注释,主要就是两段代码:
<script>
if (navigator.serviceWorker != null) {
navigator.serviceWorker.register('sw.js')
.then(function () {
console.log('Service Worker Registered');
})
}
</script>
html 这段用来检测浏览器是否支持 serviceWorker,支持就访问 sw.js 来注册,没有支持就 pass。
然后是 sw.js:
const cacheName = 'only-001'
const cacheList = [
"/",
"index.html",
"js/app.js",
"js/engines.js",
"css/app.css",
"css/app.min.css",
"static/img/icon_0.png",
"static/img/icon_1.png",
"static/img/icon_2.png",
"static/img/icon_3.png",
"static/img/icon_4.png",
"static/img/icon_5.png",
"static/img/icon_6.png",
"static/img/icon_7.png",
"static/img/logo_48.png",
"static/img/logo_96.png",
"static/img/logo_144.png"
]
// Service Worker 注册完成事件,写入缓存
self.addEventListener('install', e => {
e.waitUntil(
caches.open(cacheName)
.then(cache => cache.addAll(cacheList))
.then(() => self.skipWaiting())
)
})
// Service Worker 启动事件,处理更新缓存
self.addEventListener('activate', function(e) {
e.waitUntil(
Promise.all(
caches.keys().then(keyList => {
return keyList.map(key => {
// 遍历已有缓存,保留与当前一样的缓存,即更新
if (key !== cacheName) return caches.delete(key)
else return null
})
})
).then(() => {
return self.clients.claim()
})
)
})
// 请求接口事件,处理相关逻辑
self.addEventListener('fetch', function(e) {
e.respondWith(
// 如果缓存内容存在,则提供缓存内容,否则继续 fetch
caches.match(e.request).then(function(response) {
return response || fetch(e.request.url)
})
)
})
这里内容是 serviceWorker 的生命周期相关事件,这里不涉及通知。
注意两点:
- 最上面的 cacheName 需要在下次更新 sw.js 的时候手动修改,否则浏览器认为你没有更新这个文件,没错,这个是前端控制的,有没有瞬间能装逼的感觉?
- cacheList 我得手动一个一个加上,通配符没用,如果有小伙伴有方法的话,告知一下……
补充
PWA 还有个配套的东西可选,就是手机浏览的时候可以保存在本地,“当做”APP 使用。
配置文件 manifest.json,代码如下:
{
"name": "only u",
"short_name": "only u",
"display": "standalone",
"start_url": "/",
"theme_color": "#1f243e",
"background_color": "#1f243e",
"icons": [
{
"src": "static/img/logo_48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "static/img/logo_96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "static/img/logo_144.png",
"sizes": "144x144",
"type": "image/png"
}
]
}
各自功能如下:
标题 | 功能 |
---|---|
name | 用于显示在推荐横幅上与启动画面 |
short_name | 显示在桌面 |
display | 是否显示 Chrome UI,可选 browser |
orientation | 可选横向 landscape,可不填 |
start_url | 启动进入的页面 |
theme_color | 主题色,用于调整工具栏与 Chrome UI 颜色 |
background_color | 启动时的背景色 |
icons | 48dp 倍数,48x48, 96x96, 14x144, 192x192 自动选取桌面(48 乘以显示倍数)与启动页图标(最接近 128) |
效果如下:
这个是手机 Chrome 保存效果。
在右边,跟 APP 显示一样的。
这个欢迎屏幕显示在 manifest.json 文件里面配置了。
注意,没有浏览器的搜索框(地址栏)了,跟 APP 效果一致!
附一张“粪叉”效果,除了缩略图有问题,貌似其他都一样支持的(没做 Safari 的细节样式兼容)。
小结
- 阿里提供免费的 https 证书,比较难找,建议域名跟 https 在一个平台处理,避免不必要的麻烦。
- Express 是个好东西,谁用谁知道。
- PWA 是近几年可能的大势,早了解早好。
- Safari 也是支持 PWA,但是标准可能跟 Chrome 不同。
欢迎关注,如有需要 Web,App,小程序,请留言联系。
共同学习,写下你的评论
评论加载中...
作者其他优质文章