从WEB到PWA 开发-发布-安装
见意如题!本文主要来说说PWA开发!作为一个前端程序员,在没有任何Android/IOS的开发情况下,想想我们有多少种方法来开发一个原生移动应用程序!我们可以有非原生、混合开发,PWA等等手段。类似uniapp,Reactive native为我们提供了更简便的手段!抛开这些框架,我们该如何仅使用 HTML、CSS 和 Javascript 来开发一个多平台的标准移动程序!这就是本文要介绍的渐进式WEB应用程序(PWA)!
PWA
PWA(Progressive Web Apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。这些应用无处不在、功能丰富,使其具有与原生应用相同的用户体验优势.
--MDN
通俗的说:PWA是风格类似移动应用程序的网站!它可以运行在浏览器中也可以直接安装在移动设备上!
PWA必须包含下面三个关键内容!
- Service Worker:它运行在一个与页面JavaScript主线程的独立线程上。它提供了离线功能,允许用户从网站下载和缓存设备上的文件。
- Web Manifest:实现了将PWA网页应用 添加至桌面的功。具体的配置文件manifest.json通常放在应用的根目录,包含类似应用标题、移动设备上的图标等安装信息!但该项技术目前仍处于实验性阶段,各浏览器支持度不高!
- HTTPS:HTTP是PWA强制要求的,用来保证程序的安全性!
优点
- 跨平台可用,可以安装和运行在跨各种系统各种设备上!
- 无需下载,我们只需要访问网址,添加到桌面即可!这样就不需要第三方商店的审核!
- 不需要开发Android和IOS两套代码!
劣势
- 浏览器支持存在差异,并不是所有浏览器都完美支持!
- 调用底层硬件比原生麻烦。
- 分发效果差,因为PWA不通过应用商店,这导致你的应用无法在应用商店展示搜索!
开发
上面我们介绍了PWA的一些基础概念,下面我们就来做一个爆火在各种教程的“待办事项管理-TODO”程序!
创建项目以及目录
📂 To-Do-List
📄 index.html
📄 index.css
📄 index.js
📄 sw.js
📂 asset
页面布局(HTML)
<!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>待办清单</title><link rel="stylesheet" href="index.css">
</head><body><header><h1>欢迎使用待办清单</h1><form id="todo-form"><input type="text" name="new-todo" id="new-todo" placeholder="请输入待办事项" /><button id="submit-todo">提交</button></form></header><main><h2>待办清单</h2><div id="todos"></div></main><script src="index.js"></script>
</body></html>

添加样式

操作/存储数据
IndexedDB是可以在浏览器访问的一个完整的数据库系统!这个数据库位于浏览器中而不是本地!
因为IndexedDB操作比较复杂,MDN推荐了localForage — 小而妙的 JavaScript 库,它能使客户端数据储存很简单;默认使用 IndexDB,在不支持 IndexedDB 的浏览器中还会降级使用 WebSQL 或 localStorage!
但也是因为他的这种降级处理,使得localForage更倾向于localStorage,仅仅是一个非常简单的键值对的存储,并没有对索引外键等的支持为了构建具有更复杂需求的数据库,我推荐使用PouchDB或Dexie 之类的东西。

这里使用第三方CDN。
<script src="https://npmcdn.com/dexie/dist/dexie.js" ></script>
创建实例
这里我们创建了一个叫做ToDo的数据库,创建了一张todos的表。设置两个字段:自增主键id,todo。
const db = new Dexie("ToDo");
db.version(1).stores({ todos: "++id, todo" });
当我们刷新页面,打开开发者工具->Application->IndexedDB,可以看到我们创建的ToDo数据库!

提交事件
当按钮点击,获取input的值,然后使用add方法,添加当前数据!因为ID是自增的,所以我们不需要赋值!
const form = document.querySelector("#todo-form");
const btn = document.querySelector("#submit-todo");
btn.onclick = async (event) => {const todo = input.value;await db.todos.add({ todo });await showTodos();form.reset();
};
展示数据
定义getTodos方法来获取数据,默认取出的顺序是写入的顺序,我们需要反转才能让新添加的待办事项位于前面!
const getTodos = () => {return db.todos.reverse().toArray();
}
const showTodos = async () => {const todos = await getTodos();todos_el.innerHTML = todos && todos.map((todo) => `<div class="todo"><div class="content"><p class="text" readonly="readonly" type="text" >${todo.todo}</p></div><div class="actions"><button class="delete" οnclick="deleteTodo(event, ${todo.id})">删除</button></div></div>`).join("");
};
删除数据
const deleteTodo = async (event, id) => {await db.todos.delete(id);await showTodos();
};
配置manifest.json
在MDN上指出,可安装PWA必须存在一个配置清单。>>> https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps/Installable_PWAs, 具体的字段可以参照这个文档!
name: 网站应用的全名。short_name: 显示在主屏上的短名字。description: 一两句话解释你的应用的用途。icons: 一串图标信息:源 URL,大小和类型。多包含几个图标,这样就能选中一个最适合用户设备的。start_url: 启动应用时打开的主页。display: 应用的显示方式;可以是fullscreen、standalone、minimal-ui或者browser。theme_color: UI 主颜色,由操作系统使用。background_color: 背景色,用于安装和显示启动画面时。
{"name": "Todo PWA","short_name": "ToDo","icons": [{"src": "./assets/icon-100.png","sizes": "100x100","type": "image/png"},{"src": "./assets/icon-150.png","sizes": "150x150","type": "image/png"},{"src": "./assets/icon-250.png","sizes": "250x250","type": "image/png"}],"theme_color": "#FFFFFF","background_color": "#FFFFFF","start_url": "/PWA-Todo/","display": "standalone"
}
最后我们还需要在index.html引入
<link rel="manifest" href="manifest.json" />
注册 Service Worker
上面我们提供了安装所需的配置文件,但是仅仅也支持配置了,我们想要可以安装,还必须注册 Service Worker。
一个注册好的 Service Worker,可以让应用离线工作(这仅对于安卓设备上的 Chrome 浏览器是必需的)
我们在sw.js中来添加service worker的事件,然后再index.js中注册。
详细的设置,请参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API/Using_Service_Workers
install事件一般是被用来填充你的浏览器的离线缓存能力。这里我们将文件加入到缓存中!fetch自定义请求,每次任何被 service worker 控制的资源被请求到时,都会触发fetch事件,这些资源包括了指定的 scope 内的文档,和这些文档内引用的其他任何资源(比如index.html发起了一个跨域的请求来嵌入一个图片,这个也会通过 service worker 。)
const todo = "todo";
const assets = ["/","./index.html","./index.css","./index.js","./assets/icon-100.png","./assets/icon-150.png","./assets/icon-250.png",
];self.addEventListener("install", installEvent => {installEvent.waitUntil(caches.open(todo).then(cache => {cache.addAll(assets);}));
});self.addEventListener("fetch", fetchEvent => {fetchEvent.respondWith(caches.match(fetchEvent.request).then(res => {return res || fetch(fetchEvent.request);}));
});
index.js注册:
window.onload = ()=>{showTodos();if ("serviceWorker" in navigator) {navigator.serviceWorker.register("./sw.js").then(res => console.log("注册serviceWorker:成功")).catch(err => console.log("注册serviceWorker:失败", err));}
};
安装
PC chrome
打开PC Chrome浏览器,我们会发现在上方搜素框右边出现了一个下载按钮,如果你已经安装过了,则会编程一个箭头。至此我们已经成功的完成了PWA的开发,发布,安装!


移动Chrome
打开移动端的Chrome,可以通过菜单中的添加到主屏幕,将程序安装到本地!


国产浏览器
支持添加网址到桌面的浏览器:360浏览器、搜狗浏览器、UC浏览器、华为浏览器、QQ浏览器。但是这种方式,其实类似window的添加快捷方式,而Chrome的体验就是实打实的安装一个软件!
以UC浏览器为例:
我们打开网站,找到收藏网址:

相关文章:
从WEB到PWA 开发-发布-安装
见意如题!本文主要来说说PWA开发!作为一个前端程序员,在没有任何Android/IOS的开发情况下,想想我们有多少种方法来开发一个原生移动应用程序!我们可以有非原生、混合开发,PWA等等手段。类似uniappÿ…...
FPGA纯vhdl实现MIPI CSI2 RX视频解码输出,OV13850采集,提供工程源码和技术支持
目录1、前言2、Xilinx官方主推的MIPI解码方案3、纯Vhdl方案解码MIPI4、vivado工程介绍5、上板调试验证6、福利:工程代码的获取1、前言 FPGA图像采集领域目前协议最复杂、技术难度最高的应该就是MIPI协议了,MIPI解码难度之高,令无数英雄竞折腰…...
《NFL橄榄球》:卡罗来纳黑豹·橄榄1号位
卡罗来纳黑豹(英语:Carolina Panthers)是一支位于北卡罗来纳州夏洛特的职业美式橄榄球球队。他们是国家美式橄榄球联合会的南区其中一支球队。他们与杰克逊维尔美洲虎在1995年加入NFL,成为扩充球队。 2018年球队市值为23亿美元&am…...
我说我为什么抽不到SSR,原来是这段代码在作祟...
本文是龚国玮所写,熊哥有所新增修改删减,原文见文末。 我说我为什么抽不到SSR,原来是加权随机算法在作祟 阅读本文需要做好心理准备,建议带着深究到底的决心和毅力进行学习! 灵魂拷问 为什么有 50% 的几率获得金币&a…...
MySQL MGR 集群新增节点
前言 服务器规划现状(CentOS7.x) IP地址主机名部署角色192.168.x.101mysql01mysql192.168.x.102mysql02mysql192.168.x.103mysql03mysql192.168.x.104proxysql01proxysql、keepalived192.168.x.105proxysql02proxysql、keepalived 新增服务器IP&#x…...
【单目标优化算法】蜣螂优化算法(Dung beetle optimizer,DBO)(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
【C++】类和对象入门必知
面向过程和面向对象的初步认识类的引入类的定义类的访问限定符封装类的作用域类的实例化类对象模型this指针C语言和C实现Stack的对比面向过程和面向对象的初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解…...
day38 动态规划 | 509、斐波那契数 70、爬楼梯 746、使用最小花费爬楼梯
题目 509、斐波那契数 斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0,F(1) 1 F(n) F(n - 1) F(n - 2),其…...
2023年备考软考必须知道的6件事
不知不觉,距离2023年上半年软考也只有不到100天的时间了,报名入口也将在3月13日正式开通,你是正在犹豫是否参加考试? 还是已经开始着手准备复习? 关于软考考试你还有哪些疑问? 2023年备考软考必须知道的6件事,建议收藏…...
GLOG如何控制输出的小数点位数
1 问题 在小白的蹩脚翻译演绎型博文《GLOG从入门到入门》中,有位热心读者提问说:在保存日志时,浮点型变量的小数位数如何设置? 首先感谢这位“嘻嘻哈哈的地球人”赏光阅读了小白这不太通顺的博客文章,并提出了一个很…...
2022年全国职业院校技能大赛(中职组)网络安全竞赛试题A(6)
目录 模块A 基础设施设置与安全加固 一、项目和任务描述: 二、服务器环境说明 三、具体任务(每个任务得分以电子答题卡为准) A-1任务一:登录安全加固(Windows) 1.密码策略 a.密码策略必须同时满足大小…...
Safety-Gym环境配置与安
官网: https://github.com/openai/safety-gym https://github.com/openai/safety-starter-agents 一、安装依赖环境配置 建议使用python 3.7及以下环境,因为官方的safety-rl是基于tensorflow1.13.1实现,而tensorflow1.13.1只能支持python…...
3月再不跳槽,就晚了
从时间节点上来看,3月、4月是每年跳槽的黄金季! 以 BAT 为代表的互联网大厂,无论是薪资待遇、还是平台和福利,都一直是求职者眼中的香饽饽,“大厂经历” 在国内就业环境中无异于一块金子招牌。在这金三银四的时间里&a…...
HTTP cookie格式与约束
cookie是前端编程当中经常要使用到的概念,我们可以使用cookie利用浏览器来存放用户的状态信息保存用户做了一些什么事情。session是服务器端维护的状态。session又是如何和cookie关联起来。后面介绍cookie和session的使用。Cookie 是什么?RFC6265, HTTP …...
docker基础
docker基础 docker概述 docker的出现?docker解决思想docker历史docker链接docker能干什么?开发-运维 docker安装 镜像(image)容器(container)仓库(repository)底层原理 docker命令 帮助命令镜像命令 docker-images查看所有本地主机上的镜像docker-searc…...
【微信小程序】--JSON 配置文件作用(三)
💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &#…...
EDA-课设
EDA-课程设计-电子闹钟 一、实验目的 1.掌握多层电路在 QuartusII 集成开发环境中的实现; 2.熟练掌握基于 QuartusII 集成开发环境的组合逻辑电路设计流程; 3.掌握基于 QuartusII 集成开发环境的时序逻辑电路设计流程; 4.理解有限状态机设计…...
C/C++每日一练(20230222)
目录 1. 部分复制字符串(★) 2. 按字典顺序排列问题(★★) 3. 地下城游戏(★★★) 附录 动态规划 1. 部分复制字符串 将字符串2小写字母复制到字符串1:编写程序,输入字符串s2,将其中所有小写字母复制到字符串数组strl中。例如:aal1bb22cc33de4AA55…...
Java API 文档搜索引擎
1. 认识搜索引擎:在搜狗搜索的搜索结果页中, 包含了若干条结果, 每一个结果包含了图标, 标题, 描述, 展示URL等搜索引擎的本质:输入一个查询词, 得到若干个搜索结果, 每个搜索结果包含了标题, 描述, 展示URL和点击URL2. 搜索引擎思路:2.1 搜索的核心思路:当前我们有很多的网页(…...
2023美赛C题Wordle二三问分布预测和难度分类预测
文章目录前言题目介绍人数分布预测首先建立字母词典,加上时间特征数据预处理训练和预测函数保存模型函数位置编码模型及其参数设置模型训练以及训练曲线可视化预测人数分布难度分类预测总结前言 2023美赛选了C题,应该很多人会选,一看就好做&…...
OpenCL图像格式兼容性与性能优化指南
1. OpenCL图像格式兼容性解析在OpenCL编程中,图像处理是一个核心功能模块。图像格式的正确配置直接影响着内核程序的执行效率和结果的准确性。CL_UNSIGNED_INT8和CL_RGB作为OpenCL中常见的图像格式参数,它们的兼容性问题值得深入探讨。1.1 图像格式描述符…...
机器学习系统能源优化:Magneton框架与能效提升实践
1. 机器学习系统中的能源浪费现状在当今大规模机器学习应用场景中,能源效率已成为与计算性能同等重要的关键指标。根据行业实测数据,一个典型的大型语言模型推理任务可能消耗相当于数十个家庭日用电量的能源。这种惊人的能源消耗背后,隐藏着大…...
FactoryBluePrints:戴森球计划终极蓝图仓库使用指南
FactoryBluePrints:戴森球计划终极蓝图仓库使用指南 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints FactoryBluePrints是《戴森球计划》游戏中最大规模的工厂蓝…...
逆向分析第一步:手把手教你搭建WinDbg+VMware双机调试环境(含问题排查)
逆向工程实战:从零构建WinDbg与VMware双机调试环境调试器与虚拟机的组合是安全研究人员分析软件行为、挖掘漏洞的必备工具链。想象一下,当你需要观察一个可疑驱动程序如何与操作系统内核交互,或是追踪某个恶意样本在系统底层的活动轨迹时&…...
深度学习篇---NVIDIA DeepStream
NVIDIA DeepStream 是一个功能强大的流媒体分析工具包,专为基于 AI 的多传感器处理、视频、音频和图像理解而设计。你可以把它想象成一个“视觉 AI 应用的乐高工厂”,它把视频解码、AI 推理、目标追踪这些复杂的“零件”,巧妙地组合成一条高效…...
OpenSSH用户枚举漏洞CVE-2018-15473深度解析与修复指南
1. 这个漏洞不是“能被爆破密码”,而是“连用户名都藏不住”OpenSSH用户枚举漏洞(CVE-2018-15473)在2018年7月被公开时,很多运维同学第一反应是:“哦,又是密码爆破相关?”——这个误解直接导致大…...
NS模拟器自动化管理系统:简化游戏兼容性配置的解决方案
NS模拟器自动化管理系统:简化游戏兼容性配置的解决方案 【免费下载链接】ns-emu-tools 一个用于安装/更新 NS 模拟器的工具 项目地址: https://gitcode.com/gh_mirrors/ns/ns-emu-tools NsEmuTools是一款专为Nintendo Switch模拟器用户设计的桌面端管理解决方…...
【读书笔记】《更富有、更睿智、更快乐》
《更富有、更睿智、更快乐》精读笔记作者威廉格林历时25年,贴身采访全球40余位顶级投资大师,包括芒格、巴菲特等人,总结出一套投资与人生的双赢哲学。核心命题顶级投资者本质上是一类实践哲学家——他们不谈空理论,只追求世俗智慧…...
PICO Unity APK闪退的五大根因与工程化排查指南
1. 为什么PICO项目打包APK后“秒退”不是玄学,而是可定位的工程链路断裂 “Unity打包PICO APK闪退”——这六个字在XR开发群、技术论坛和外包项目交接现场出现的频率,几乎和“黑屏”“白屏”“加载失败”并列成为移动端开发三大幽灵问题。我接手过27个P…...
集成学习在恒星自转周期估计中的应用:从特征工程到模型投票
1. 项目概述与核心挑战在系外行星探测领域,我们常常面临一个“信号分离”的难题:如何从恒星持续变化的光度信号中,准确无误地揪出那颗可能存在的行星划过恒星表面时产生的微弱“凌星”信号。这就像在一场喧闹的摇滚音乐会上,试图听…...
