资讯专栏INFORMATION COLUMN

pwa-之service worker 基本概念

galaxy_robot / 2611人阅读

摘要:是浏览器和服务器之间的脚本,主要作用是拦截请求,修改响应,以及一些其他的作用。这是出于安全因素的考虑。这个注册的过程是发生在之外的。在安装完成,激活之前,它不会拦截任何请求。将会始终拦截请求,重启页面也是为了这个。

pwa-之service worker 基本概念
pwa-之service worker 离线文件处理

学习service worker 基本概念

在本章,将涵盖以下内容

service worker准备工作

注册service worker

注册service worker细节

调试

出现错误时提供稳定版本

创建mock响应

处理请求超时

简介

如果你是一个旅行爱好者,应该会经常陷入没有网络的情况。这是令人沮丧的。特别是你有事情的时候。

service worker是一个在==浏览器后台==运行的脚本。无论网络连接如何,能够使用Web应用程序意味着用户可以在飞机,地铁或连接受限或不可用的地方不间断地操作。 该技术将有助于提高客户端的工作效率,并将提高应用程序的可用性。

通过service worker,我们可以预先缓存网站的某些资源。 我们作为资源引用的是JavaScript文件,CSS文件,图像和一些字体。 这将有助于我们加快加载时间,而不必每次访问同一网站时都必须从服务器获取。 当然,最重要的是,当我们网络不畅时,这些资源将可供我们使用。

Service workers

service worker是浏览器和服务器之间的脚本,主要作用是拦截请求,修改响应,以及一些其他的作用。

网站可以正常工作的前提是能获取到html,css,js等资源。在之前这些资源主要由浏览器管理,对于开发者而言是不可见的。现在通过service worker我们可以掌控这些资源。当然最终还是通过浏览器控制他们的。

掌握service worker的前提是掌握promise

Promise

Promise是用于处理异步操作的很好的方式,对于掌握service worker是至关重要的。

Promise功能很强大,我们不在这里细述了。我们只需要知道调用then()方法处理成功,catch方法处理错误就可以了。

一个简单的比较同步和异步操作的代码

sync
    try {
        var value = Fn();
        console.log(value);
    } catch(err) {
        console.log(err);
    }
    
async
    Fn()
    .then(function(value) {
        console.log(value);
    })
    .catch(function(err) {
        console.log(err);
    });
service worker准备工作

Service workers能够运行的前提是网站采用了https。这是出于安全因素的考虑。

现在主流浏览器都已经支持service worker,不需要去多带带开启了。

虽然service worker一定要在https的域名下面运行,但是本地的http://localhost域名却不影响,可以正常运行。

注册service worker

一个service worker如果要生效,必须要先注册。这个注册的过程是发生在service worker之外的。一般会在index.html中。你可以写在js文件里面,在html文件中引入,但不能在service worker的js中注册。

如何注册

先创建一个html文件





    

Registration status:

在当前文件夹下面创建一个==名字叫service-worker.js==的js文件

启动一个本地服务器,推荐使用anywhere,自带了https

成功图示

![image](http://wx2.sinaimg.cn/mw690/0...
)

程序如何运行

首先判断浏览器支持情况,如果不支持则做出提示。

我们使用了空js文件注册了service worker。register的第二个参数的scope表示此service worker的作用范围是当前域名下面的根目录。

如图显示:注册成功。说明我们的浏览器是支持service worker的。

卸载service worker

通过调用unregister()方法卸载service worker

serviceWorker.unregister().then(function() {
    document.getElementById("status").innerHTML = "unregistered";
})
注册service worker的详细信息

了解service worker注册过程中的详细信息和事件有助于我们更好的掌控它。

注册详情

我们创建一个如下的html页面




  
  Detailed Registration


  

Registration status:

State:

创建一个service-worker.js文件

self.addEventListener("install", function(e) {
  console.log("Install Event:", e);
});

self.addEventListener("activate", function(e) {
  console.log("Activate Event:", e);
});

然后页面如下显示

程序如何运行

上面的代码描述了service worker的3种状态。当程序处于active状态的时候,我们就可以刷新页面查看处于service worker控制之下的页面了。

在service worker中我们注册了两个事件,installactivate,当service worker第一次注册的时候会被触发。

install事件比较适合用来预加载数据和初始化缓存,activate事件适合用来清理旧版本的数据。

其他

当一个service worker被成功注册,它会经历以下状态

Install

在service worker的生命周期中,如果service worker已经注册没有错误,但是尚未激活。那之前已经激活的service worker就会仍然会控制着页面。重新加载之后的service worker如果发生任何更改,就会重新安装service worker。在安装完成,激活之前,它不会拦截任何请求。

Activate

当service worker被激活时,它的状态就是activate。service worker就可以拦截请求了。只有当我们关闭网页重新打开,或者强制刷新当前页面,才会被激活。一般安装成功之后不会立即处于activate状态。

Fetch

在当前scope作用域下面的请求会触发fetch事件

Terminate

这个事件可能会发生在任何时候,主要后果就是需要浏览器做service worker的内存回收。之后根据需要重启,但不是不会在触发activate事件。

service worker将会始终拦截请求,重启页面也是为了这个。虽然这么说,但我们无法保证service worker任何时候都处于生效状态,所以在service worker中定义的全局状态可能不会被保留。所以我们最好使用indexDB和localStorage来实现持久化。

调试

service worker在浏览器中多带带线程运行,通过多带带的方式和页面通信。但是和页面是处于不同的作用域。这就意味着service worker无法访问网页的dom等其他信息。因此我们也无法通过
DevTools里面同一个tab来调试service worker。我们需要一个多带带的Tab来调试service worker线程。

在service worker中,它大部分的工作是在监听的事件中来完成的,比如在install事件中完成资源缓存。同样我们可以在这里打断点。

怎么做

下面来展示如何调试

在chrome中打开:chrome://inspect/#service-workers

或者在chrome中输入:chrome://serviceworker-internals/ 如果列表里面没有的话,说明没有service worker正在运行

在DevTools中的Source下面的service worker可以看到对应的js脚本

在这里可以调试

同样可以使用console.log

chrome://serviceworker-internals/页面中,可以看到每个service worker下面有几个按钮。

Terminated:注销service worker

Start/Stop: 开启/停止service worker

Sync: 给worker同步Sync事件

push: 给worker同步push事件

Inspect:在检查器中打开worker

==即使勾选了Network中的disable cache,service worker依然会生效,如果需要每次都更新,需要勾选Application->service worker->offline==

发生错误时提供稳定版本

创建一个html文件




  
  Stale on Error


  

Registration status:

创建service-worker.js文件

var version = 1;
var cacheName = "stale-" + version;

self.addEventListener("install", function(event) {
    self.skipWaiting();
});

self.addEventListener("activate", function(event) {
    if (self.clients && clients.claim) {
        clients.claim();
    }
});

self.addEventListener("fetch", function(event) {
    // Always fetch response from the network
    event.respondWith(
        fetch(event.request).then(function(response) {
            return caches.open(cacheName).then(function(cache) {
                // If we received an error response
                if(response.status >= 500) {
                    return cache.match(event.request).then(function(response) {
                        // Return stale version from cache
                        return response;
                    }).catch(function() {
                        // No stale version in cache so return network response
                        return response;
                    });
                } else {
                    // Response was healthy so update cached version
                    cache.put(event.request, response.clone());
                    return response;
                }
            });
        })
    );
});

当网络中断之后,页面依然可以访问。

创建mock响应

我们可以模拟服务器,对客户端进行响应。

创建index.html页面




  
  Detailed Registration


  

Network status:

Mock Response

创建service-worker.js

self.addEventListener("fetch", function(event) {
  var requestUrl = new URL(event.request.url);

  if (requestUrl.pathname === "/urlshortener/v1/url" &&
      event.request.headers.has("X-Mock-Response")) {

    var response = {
      body: {
        kind: "urlshortener#url",
        id: "https://goo.gl/KqR3lJ",
        longUrl: "https://www.packtpub.com/books/info/packt/about"
      },
      init: {
        status: 200,
        statusText: "OK",
        headers: {
          "Content-Type": "application/json",
          "X-Mock-Response": "yes"
        }
      }
    };

    var mockResponse = new Response(JSON.stringify(response.body), response.init);

    console.log("Mock Response: ", response.body);
    event.respondWith(mockResponse);
  }
});

可以看到页面显示的是service worker里面我们配置的响应

处理请求超时

请求超时有可能是网络连接的问题,service worker是解决这类问题的理想方案。

创建html文件




  
  Request Timeouts


  

Registration status:

创建service-worker.js

function timeout(delay) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(new Response("", {
                status: 408,
                statusText: "Request timed out."
            }));
        }, delay);
    });
}

self.addEventListener("install", function(event) {
    self.skipWaiting();
});

self.addEventListener("activate", function(event) {
    if (self.clients && clients.claim) {
        clients.claim();
    }
});

self.addEventListener("fetch", function(event) {
  if (/.js$/.test(event.request.url)) {
    event.respondWith(Promise.race([timeout(400), fetch(event.request.url)]));
  } else {
    event.respondWith(fetch(event.request));
  }
});

当我们把jquery地址换成一个错误的地址,我们看到一个408的响应。

关注我的微信公众号,更多优质文章定时推送

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108243.html

相关文章

  • pwa-service worker 基本概念

    摘要:是浏览器和服务器之间的脚本,主要作用是拦截请求,修改响应,以及一些其他的作用。这是出于安全因素的考虑。这个注册的过程是发生在之外的。在安装完成,激活之前,它不会拦截任何请求。将会始终拦截请求,重启页面也是为了这个。 pwa-之service worker 基本概念pwa-之service worker 离线文件处理 学习service worker 基本概念 在本章,将涵盖以下内容 ...

    olle 评论0 收藏0
  • 前端每周清单半年盘点 PWA

    摘要:前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎关注【前端之巅】微信公众号(ID:frontshow),及时获取前端每周清单;本文则是对于...

    崔晓明 评论0 收藏0
  • pwa-service worker 离线文件处理

    摘要:勾上刷新页面,显示如图实现原理使用,预先缓存和。又请求已经缓存好的。加载离线图片创建创建创建访问,然后打开。一定要访问啊,不然不会成功多个事件调用事件和其他事件一样都是可以注册多次的。 pwa-之service worker 基本概念pwa-之service worker 离线文件处理 本章包含以下知识点 显示离线页面 加载离线图片 加载离线css 多个fetch处理事件调用 简介...

    fizz 评论0 收藏0
  • pwa-service worker 离线文件处理

    摘要:勾上刷新页面,显示如图实现原理使用,预先缓存和。又请求已经缓存好的。加载离线图片创建创建创建访问,然后打开。一定要访问啊,不然不会成功多个事件调用事件和其他事件一样都是可以注册多次的。 pwa-之service worker 基本概念pwa-之service worker 离线文件处理 本章包含以下知识点 显示离线页面 加载离线图片 加载离线css 多个fetch处理事件调用 简介...

    mylxsw 评论0 收藏0
  • PWA学习与实践】(3) 让你的WebApp离线可用

    摘要:学习与实践系列文章已整理至学习手册,文字内容已同步至。本文是学习与实践系列的第三篇文章。引言其中一个令人着迷的能力就是离线可用。但是,如果你注意到文章开头的图片就会发现,离线时我们不仅可以访问,还可以使用搜索功能。 《PWA学习与实践》系列文章已整理至gitbook - PWA学习手册,文字内容已同步至learning-pwa-ebook。转载请注明作者与出处。 本文是《PWA学习与实...

    since1986 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<