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. Java 中线程池的 7 种创建方式!

    在 Java 语言中,并发编程都是通过创建线程池来实现的,而线程池的创建方式也有很多种,每种线程池的创建方式都对应了不同的使用场景,总体来说线程池的创建可以分为以下两类: 通过 ThreadPoolE ...

  2. Java中ArrayList和LinkedList的异同

    一:ArrayList和LinkedList的大致区别如下: 1.ArrayList是实现了基于动态数组的数据结构,ArrayList实现了长度可变的数组,在内存中分配连续的空间.遍历元素和随机访问元 ...

  3. Mysql高级操作学习笔记:索引结构、树的区别、索引优缺点、创建索引原则(我们对哪种数据创建索引)、索引分类、Sql性能分析、索引使用、索引失效、索引设计原则

    Mysql高级操作 索引概述: 索引是高效获取数据的数据结构 索引结构: B+Tree() Hash(不支持范围查询,精准匹配效率极高) 树的区别: 二叉树:可能产生不平衡,顺序数据可能会出现链表结构 ...

  4. while + else 使用,while死循环与while的嵌套,for循环基本使用,range关键字,for的循环补充(break、continue、else) ,for循环的嵌套,基本数据类型及内置方法

    今日内容 内容概要 while + else 使用 while死循环与while的嵌套 for循环基本使用 range关键字 for的循环补充(break.continue.else) for循环的嵌 ...

  5. VUE3 之 多个元素之间的过渡 - 这个系列的教程通俗易懂,适合新手

    1. 概述 老话说的好:过去不等于未来,过去成功了不代表将来也会成功,过去失败了也不代表将来也会失败. 言归正传,今天我们聊聊多个元素之间的过渡. 2. 多个元素之间的过渡 2.1 两个元素交替显示 ...

  6. tp5 ajax批量删除(自写)

    html代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  7. shuffle()和sns.FacetGrid()定义

  8. 还不会用springboot写接口?快看这里,手把手操作,一发入魂~

    1.springboot简介 Spring Boot 可以轻松创建可以"直接运行"的独立的.生产级的基于 Spring 的应用程序. 特征 创建独立的 Spring 应用程序 直接 ...

  9. webug4.0 打靶笔记-02【完结】

    webug4.0打靶笔记-02 3. 延时注入(时间盲注) 3.1 访问靶场 3.2 寻找注入点 貌似一样的注入点: ?id=1' --+ 3.3 判断输出位置 同前两关一样的位置,时间盲注应该不是这 ...

  10. 2.3 C++STL vector容器详解

    文章目录 2.3.1 引入 2.3.2 代码实例 2.3.3 运行结果 总结 2.3.1 引入 vector 容器 动态数组 可变数组 vector容器 单口容器(尾部操作效率高) vector动态增 ...