PWA(Progressive Web App)是前端的大趋势,它能极大的加快前端页面的加载速度,得到近乎原生 app 的展示效果(其实难说)。PWA 其实是多种前端技术的组合,其中最重要的一个技术就是 service worker。

Service worker 在 MDN 上的说明:

Service workers 本质上充当Web应用程序与浏览器之间的代理服务器,也可以在网络可用时作为浏览器和网络间的代理。它们旨在(除其他之外)使得能够创建有效的离线体验,拦截网络请求并基于网络是否可用以及更新的资源是否驻留在服务器上来采取适当的动作。他们还允许访问推送通知和后台同步API。

其实不用太纠结,简单起见我们就把它当成更高级更先进的 AppCache 就好了。

在 nuxt(Vue) 网站中启用 Service worker

借近期公司官网升级之机,我也给公司官网上了 Service worker 做离线缓存。

大前提:Service worker 只可在 https(或 localhost)下使用,首先确保你的网站上了 https

在 nuxt 程序中启用 Service worker 非常方便。nuxt 提供了官方 module——pwa-module 用于支持 PWA 网站,其中就包含了用于实现 Service worker 的 workbox moduleworkbox 实际上是指的 google 为简化 Service worker 开发而开源的第三方库。

首先安装依赖

$ yarn add @nuxtjs/pwa @nuxtjs/workbox

然后再配置文件中启用

// modules
module.exports = {
[ '@nuxtjs/pwa' ]
}

就完成了

SW 使用采坑

官网上线后发现,启用 Service worker 后 Safari 不能播放视频了。但是直接输入视频链接却可以播放。经过各种 google 搜索查资料后找到了官方 issue:

  1. https://github.com/nuxt-commu...
  2. https://github.com/angular/an...

甚至还找到了有人给 webkit(Safari 浏览器内核)开了bug:https://bugs.webkit.org/show_...

状态始终是 new,没有人解决。但 issue 中详细说明了 Safari 的行为以及产生问题的原因

问题的原因在于对于视频文件请求,浏览器会发出带有 Range 头的请求部分获取文件内容。Safari 比较奇葩,对于视频文件请求,它一开始就会发一个 Range: 0-1 的请求,但是 Service worker 中处理请求的逻辑不能识别 Range 请求,把 Range 请求当成普通请求处理,返回了 200。Safari 把 200 当成了失败请求,导致请求视频文件失败。

最后开各人的回帖找到了这里:https://developers.google.com...

然后经过各种尝试(中间过程略),说一下可行方案:

首先添加 js plugin:

// workbox-range-request.js
workbox.routing.registerRoute(
/.*\.(mp4|webm)/,
workbox.strategies.cacheFirst({
plugins: [
new workbox.rangeRequests.Plugin(),
],
}),
'GET'
);

这个文件给 workbox 注册一个路由,指定对于视频文件(以 .mp4 或 .webm 结尾的文件。如果你的网站有音频文件也要一并处理)处理程序添加 rangeRequests 插件

然后在配置文件中注册插件:

// modules:
[ '@nuxtjs/pwa', {
workbox: {
cachingExtensions: '@/plugins/workbox-range-request.js',
}
} ],

注意必须使用 cachingExtensions 而不能用 routingExtensions,虽然注册的是路由配置

这样 Service worker 就可以处理带 Range 头的请求了,但是还不算完。workbox 会请求 googlecdn 动态加载 js 脚本,如果你身在兲朝,由于众所周知的原因加载脚本会失败。

解决方案:

  1. 首先去 workbox 官网下载 release 包(笔者用的是 3.5.0 版本):https://github.com/GoogleChro...
  2. 解压后放在你项目的 static 文件夹下,笔者是 static/workbox-v3.5.0
  3. 修改配置
// modules:
[ '@nuxtjs/pwa', {
meta: false,
workbox: {
config: { modulePathPrefix: '/workbox-v3.5.0' },
cachingExtensions: '@/plugins/workbox-range-request.js',
}
} ],

配置中指定 workbox 从 /workbox-v3.5.0 这个路径加载 js 脚本,而不走 googlecdn。

注意配置中使用的 config 当前版本(@nuxtjs/pwa@2.5.0, 2018-09-20)还不支持,笔者给官方仓库开了 Pull request 还在审核中,笔者是直接修改了 node_modules 里的文件。

在上 Service worker 之前最好想清楚。这玩意和 AppCache 一样,上线简单,想要下线就难了

请上公司官网体验效果:https://www.eoitek.com

本文转载于:猿2048https://www.mk2048.com/blog/blog.php?id=h0caka2ahbb

Service worker (@nuxtjs/workbox) 采坑记的更多相关文章

  1. 分布式改造剧集之Redis缓存采坑记

    Redis缓存采坑记 ​ 前言 ​ 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...

  2. Spring Cloud Config采坑记

    1. Spring Cloud Config采坑记 1.1. 问题 在本地运行没问题,本地客户端服务能连上本地服务端服务,可一旦上线,发现本地连不上线上的服务 服务端添加security登录加密,客户 ...

  3. k8s采坑记 - 解决二进制安装环境下证书过期问题

    前言 上一篇k8s采坑记 - 证书过期之kubeadm重新生成证书阐述了如何使用kubeadm解决k8s证书过期问题. 本篇阐述使用二进制安装的kubernetes环境,如何升级过期证书? k8s配置 ...

  4. Redis适配采坑记

    Redis适配采坑记 相对于其他的适配,Redis可以说是非常简单的其中只发现一个坑 问题一: 问题描述: redis认证失败 问题详解: redis连接配置时,本地需要采用password属性,远程 ...

  5. tk.mybatis通用工具采坑记

    tk.mybatis通用工具pom <!--mybatis依赖--> <dependency> <groupId>org.mybatis.spring.boot&l ...

  6. dubbo初学采坑记

    写在前面的话 dubbo 现在是apache组织旗下的项目,相信国内也有很多人使用.最近一个同事离职,我就接手了他的项目.远程通讯就是用的dubbo框架来实现的.使用Intelij idea 写了一个 ...

  7. aidl使用采坑记

    什么是AIDL? AIDL是 Android Interface definition language的缩写,它是一种Android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口 A ...

  8. 几行代码把Chrome搞崩溃之:HTML5 MP3录音由ScriptProcessorNode升级成AudioWorkletNode采坑记

    关键词: STATUS_ACCESS_VIOLATION AudioContext AudioWorkletNode audioWorklet addModule resume suspended c ...

  9. css选择器:first-child和nth-child 采坑记

    今天想用nth-child来给一个类似于树的目录(bootstrap-nav-tree  一个angularjs插件)设置不同的颜色,结构大致类似于 <ul> <li class=& ...

随机推荐

  1. 超简单的集成表达式树查询组件,Sy.ExpressionBuilder 使用说明

    Sy.ExpressionBuilder是一套依赖于表达式树上的集成的查询组件.设计的初衷没别的,就为了少写代码,让查询业务可以变得更加模式化.目前可以从nuget 获取到该组件. 来到查询,查询实体 ...

  2. Django的models由数据库表生成

    Django的models由数据库表生成 参考文献:https://www.cnblogs.com/sukura/p/14306510.html 目的或效果:方便实现使用django原生的后台管理系统 ...

  3. MIPI CSI-2 像素打包格式解析

    背景 MIPI CSI-2支持YUV.RGB和RAW data三种数据格式,这里是个笼统的叫法,具体又根据不同的像素打包方式细分为具体的格式,打包是什么概念?就是把Sensor采样得到的RGB三个通道 ...

  4. Chapter04 运算符(Operator)

    Chapter04 运算符 目录 Chapter04 运算符 4.1 算数运算符 4.2 关系运算符 4.3 逻辑运算符 4.4 赋值运算符 4.5 三元运算符 4.6 运算符的优先级 4.7 标识符 ...

  5. Spring Cloud Gateway 不小心换了个 Web 容器就不能用了,我 TM 人傻了

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

  6. 1、mysql数据库的数据目录结构

    查看mysql的主要目录结构 通过命名查看mysql的目录结构:find / -name mysql 1.1数据库文件的存放路径 MySQL数据库文件的存放路径:/var/lib/mysql/ 1.2 ...

  7. pycharm实用常用快捷键

    我们在实用pycharm时候,可以使用一些快捷键来帮助我们写代码. 1 alt + enter 快速导包,在需要导入包时候可以使用这个快捷键: 2 alt + 1 可以快速打开或者关闭左侧projec ...

  8. SpringBoot——两种传参方式

    ?传参 举例:http://localhost:8082/news/asset/getDatas?page=1&keyWord=123&year=2020 注解:@RequestPar ...

  9. 如果一个service服务出现异常,无响应,如何定位,定位过程

    假设一个service服务出现异常,要如何定位

  10. 12.9 supper

    Super super的注意事项 super可以用来在子类中访问父类的public属性或方法,super只能出现在子类中. super()调用的是父类的默认无参构造,super(参数)可以调用父类的有 ...