开发一个PWA网站(教程, 入门)

栏目: 前端 · 发布时间: 5年前

内容简介:PWA: Progressive Web Apps (渐进式Web应用程序)用PWA技术开发的网页, 如果将其保存在手机桌面上, 很难将其与手机上其它app区分开, 另外它还自带了缓存, 推送功能, 简直不要太爽, 下面介绍一下PWA网页的开发过程这一篇不介绍推送, 因为推送要服务端支持, 所以这里只创建一个静态项目就可以了

PWA: Progressive Web Apps (渐进式Web应用程序)

用PWA技术开发的网页, 如果将其保存在手机桌面上, 很难将其与手机上其它app区分开, 另外它还自带了缓存, 推送功能, 简直不要太爽, 下面介绍一下PWA网页的开发过程

创建项目

这一篇不介绍推送, 因为推送要服务端支持, 所以这里只创建一个静态项目就可以了

创建一个项目文件夹(pwa-demo) 在文件夹里创建 index.html app.css app.js

开发功能

index.html 里引入好css, js文件, 如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>CNodeJS PWA</title>
    <link rel="stylesheet" href="app.css" />
  </head>
  <body>
    <!-- ,
  "splash_pages": null -->
    <h1>CNodeJS</h1>
    <div id="main"></div>
    <script src="app.js"></script>
  </body>
</html>

app.js 文件里写入请求接口的业务逻辑, 我这里用的是 cnodejs.org 的接口

const main = document.getElementById("main");

window.addEventListener("load", e => {
  loadTopics();
});

async function loadTopics() {
  const res = await fetch(`https://cnodejs.org/api/v1/topics`);
  const json = await res.json();
  main.innerHTML = await json.data.map(createTopic).join("\n");
}

function createTopic(topic) {
  return `
    <div class="topic">
      <img src="${topic.author.avatar_url}" alt=""/>
      <div class="title">${topic.title}</div>
    </div>
  `;
}

原接文链: https://tomoya92.github.io/2019/05/23/pwa-cache/

给页面加上点css

.topic {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  padding-top: 10px;
  padding-bottom: 10px;
  border-bottom: 1px dashed #222;
}

.topic:first-child {
  padding-top: 0;
}

.topic:last-child {
  border-bottom: 0;
}

.topic img {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  margin-right: 10px;
}

.topic .title {
  -webkit-box-flex: 1;
      -ms-flex: 1;
          flex: 1;
  font-weight: 500;
  font-size: 18px;
}

打开 index.html 可以看到长这个样

开发一个PWA网站(教程, 入门)

添加Manifest

可以打开这个网站 https://app-manifest.firebaseapp.com/ , 把一些网页的信息和icon图标都填上, 点击生成, 就完事了

我在chrome里用这个网站生成的zip包里死活没有icons, 后来换成firefox就好了,不知道为啥

icon原图最好是512x512大小的

生成好之后, 把zip包解压, 将里面的文件复制到项目里

然后修改 index.html 文件内容, 在 head 里加上下面内容

<head>
  <link rel="manifest" href="manifest.json" />
</head>

打开浏览器控制台, 可以在 Application 选项里看到 Manifest 的信息

开发一个PWA网站(教程, 入门)

添加 serviceWorker

现在给网页加上缓存, 这样只要网页加载过一次, 就会把请求的数据都缓存下来, 在没有网络的环境下就可以继续查看了

app.js 里注册 serviceWorker

window.addEventListener("load", e => {
  loadTopics();
  // 注册 serviceWorker
  if ("serviceWorker" in navigator) {
    try {
      navigator.serviceWorker.register("sw.js");
      console.log("serviceWorker register success!");
    } catch (error) {
      console.log("serviceWorker register failure!");
    }
  }
});

注册的 serviceWorker 文件名是 sw.js 所以要在项目根目录下创建 sw.js 文件

链原接文: https://tomoya92.github.io/2019/05/23/pwa-cache/

然后加上如下代码

self.addEventListener("install", async event => {
  console.log('sw install');
});

self.addEventListener("fetch", async event => {
  console.log('sw fetch');
});

运行网页可以看到控制台里有打印 sw install 字样, 表示 serviceWorker 注册成功了

添加缓存

如果没有缓存功能, 好像没法将网页保存在桌面上, 下面就来添加浏览器自带的缓存功能

首先将项目里一些静态文件缓存了, 比如 app.css app.js

const staticAssets = ["./", "./app.css", "./app.js"];

self.addEventListener("install", async event => {
  const cache = await caches.open("static-assets");
  cache.addAll(staticAssets);
});

然后是对网络请求数据的缓存逻辑算是, 写法是固定的, 如下

self.addEventListener("fetch", async event => {
  const req = event.request;
  const url = new URL(req.url);

  if (url.origin === location.origin) {
    event.respondWith(cacheFirst(req));
  } else {
    event.respondWith(networkFirst(req));
  }
});

async function cacheFirst(req) {
  const cachedResponse = await caches.match(req);
  return cachedResponse || fetch(req);
}

async function networkFirst(req) {
  const cache = await caches.open("topics-dynamic");
  try {
    const res = await fetch(req);
    cache.put(req, res.clone());
    return res;
  } catch (error) {
    return await cache.match(req);
  }
}

再次运行网页, 这时候就可以将其保存在手机桌面上了

不过当保存的时候会发现没有icon, 然后我百度了一下, 还要在 index.html 里配置上下面这些东西

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>CNodeJS PWA</title>
  <link rel="stylesheet" href="app.css" />
  <link
    rel="shortcut icon"
    href="images/icons/icon-72x72.png"
    type="image/x-icon"
  />
  <!-- Specifying a Webpage Icon for Web Clip for Safari -->
  <link rel="apple-touch-icon" href="images/icons/icon-192x192.png" />
  <!-- Specifying a Launch Screen Image for Safari
  <link rel="apple-touch-startup-image" href="assets/imgs/splash.png" />-->
  <!-- Hiding Safari User Interface Components -->
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <!-- Changing the Status Bar Appearance
  <meta name="apple-mobile-web-app-status-bar-style" content="black">-->
  <link rel="manifest" href="manifest.json" />
</head>

这样再用手机浏览器打开, 然后选择保存到桌面上,就有icon了, 保存成功后, 打开让数据请求接口加载完, 然后将手机网络关了, 刚打开的应用退出后台, 再次打开会发现数据照常加载了, 只不过是缓存里的

开发一个PWA网站(教程, 入门)

如果再给其加上推送功能, 是不是就跟手机上装的app没两样了, 下一篇来介绍一下serviceWorker的推送功能用法

原文链接:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ACM国际大学生程序设计竞赛亚洲区预选赛真题题解

ACM国际大学生程序设计竞赛亚洲区预选赛真题题解

郭炜 / 电子工业 / 2011-7 / 49.00元

ACM国际大学生程序设计竞赛(ACM International Collegiate Programming Contest,简称ACM/ICPC)是世界上历史最悠久,规模最大、最具声望的程序设计竞赛,一直受到众多国际知名大学的重视,全球著名IT公司更是争相招募竞赛的优胜者。 该项赛事分为各大洲预选赛和全球总决赛两个阶段。北京大学多次在亚洲区预选赛中负责命题工作,是中国在ACM/ICPC命......一起来看看 《ACM国际大学生程序设计竞赛亚洲区预选赛真题题解》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试