Service Worker 图片加载失败处理

栏目: JavaScript · 发布时间: 7年前

内容简介:/*新

Service Worker 图片加载失败处理

参考文档

Service Worker 图片加载失败处理

git clone https://gitee.com/wjj0720/Service-Worker.git
运行 npm i 
npm start
访问 http://127.0.0.1:3000/pages/index.html  

打开控制台  刷新(由于demo做的是后加载 需刷新后 看效果)

ctrl + c 结束node服务 再次刷新页面(从缓存里面读取 依然显示页面)

简介

  • 背景

    有一个困扰 web 用户多年的难题——丢失网络连接。之前的尝试 — AppCache — 看起来是个不错的方法,但是,它假定你使用时会遵循诸多规则,如果你不严格遵循这些规则,它会把你的APP搞得一团糟。Service worker 最终要去解决这些问题。虽然 Service Worker 的语法比 AppCache 更加复杂,但是你可以使用 JavaScript 更加精细地控制 AppCache 的静默行为。有了它,你可以解决目前离线应用的问题,同时也可以做更多的事。 Service Worker 可以使你的应用先访问本地缓存资源,所以在离线状态时,在没有通过网络接收到更多的数据前,仍可以提供基本的功能(一般称之为 Offline First)。这是原生APP 本来就支持的功能,这也是相比于 web app,原生 app 更受青睐的主要原因。

  • 什么是Service Worker ?

    Service Worker是浏览器在后台启动的一条服务Worker线程

  • 功能和特性:

    1.一个独立的 worker 线程,且只有一个。
      2.一旦被 install,就永远存在,除非被 uninstall
      3.需要的时候可以直接唤醒,不需要的时候自动睡眠(此处有坑)
      4.可代理请求和返回,缓存文件,缓存的文件可以被网页进程取到
      5.能向客户端推送消息
      6.不能直接操作 DOM
      7.出于安全的考虑,必须在 HTTPS/localhost  环境下才能工作
      8.异步实现,内部大都是通过 Promise 实现
      9.基于[web worker](http://www.ruanyifeng.com/blog/2018/07/web-worker.html)

使用

1. 注册
  ```js
  // 兼容判断
 if ("serviceWorker" in navigator) {
  // 一般考虑加载问题 windoe.onload后加载
  window.addEventListener("load", function() {
    // scope 参数是选填的,可以被用来指定你想让 service worker 控制的内容的子目录
    navigator.serviceWorker.register("/sw.js", {scope: '/'})
      .then(function(registration) {
        // 注册成功
        console.log( "ServiceWorker registration successful with scope: ", registration.scope )
      })
      .catch(function(err) {
        // 注册失败
        console.log("ServiceWorker registration failed: ", err)
      });
  })
}
2. 使用
const precacheVersion = 2
  const precacheName = "precache-v" + precacheVersion

  var precacheFiles = [
    "/pages/index.html",
    "/images/dmx.jpg",
    "/images/broken.png"
  ]

/*新

  • SW.js 浏览器会自动检查差异性
  • 发生变更 install 事件被触发 此时,旧的 SW 还在工作,新的 SW 进入 waiting 状态。
  • 注意,此时并不存在替换接管,当你现在已经打开的页面关闭时,那么旧的 SW 则会被 kill 掉。
  • 新的 SW 就开始接管页面的缓存资源。 一旦新的 SW 接管,则会触发 activate 事件。

*/

self.addEventListener("install", e => {

console.log("[ServiceWorker] Installed")

// skipWaiting() 方法跳过 waiting 状态,然后会直接进入 activate 阶段

self.skipWaiting()

e.waitUntil(
  caches.open(precacheName).then(cache => {
    // 如果其中有一个 加载失败 那就代表着--这次启动 GG  
    return cache.addAll(precacheFiles)

    // cache.put(request, response).then(function() {
    //   // 成功缓存
    // });
  })
)

})

self.addEventListener("activate", e => {

console.log("[ServiceWorker] Activated")

e.waitUntil(
  caches.keys().then(cacheNames => {
    return Promise.all(
      cacheNames.map(thisCacheName => {
        if ( thisCacheName.includes("precache") && thisCacheName !== precacheName ) {
          return caches.delete(thisCacheName)
        }
      })
    )
  })
)

// 更新客户端
// self.clients.claim()

})

// 监听页面的请求 (不仅仅是js请求)

self.addEventListener("fetch", e => {

e.respondWith(
  caches.match(e.request).then(response => {
    // 有缓存走缓存
    if (response) {
      return response
    }

    return fetch(e.request) .then(fetchResponse => {

      // console.log('s-->', fetchResponse);
      if (fetchResponse.ok) return fetchResponse;
      // 加载失败的情况下 入股是图片 则返回默认图片
      if (isImage(e.request)) {
        return returnBrokenImg()
      }

      
    }).catch(err => {
      if ( isImage(e.request) ) {
        return returnBrokenImg()
      }
    })
  })
)

})

function isImage(fetchRequest) {

return fetchRequest.method === "GET" && fetchRequest.destination === "image";

}

function returnBrokenImg () {

return caches.match('/images/broken.png').then(response => response)

}

// 监听页面发来的消息

self.addEventListener('message', function (message, e) {

console.log('service接受到的数据--->', message, e);
sendMessageToPage('嘟嘟嘟')

});

// 向页面发送消息

function sendMessageToPage (msg) {

self.clients.matchAll().then(function (clients) {
  if (clients && clients.length) {
    clients.forEach(function (client) {
      client.postMessage(msg);
    })
  }
})

}

3. 客户端更新
> 除了由浏览器触发更新之外,如果24小时没有更新,会强制更新。这意味着最坏情况下Service Worker会每天更新一次
//localStorage 存下 版本  运行时候对比
var version = 'precache-v3'
navigator.serviceWorker.register('/sw.js').then(function (reg) {
  if (localStorage.getItem('sw_version') !== version) {
    reg.update().then(function () {
      localStorage.setItem('sw_version', version)
    });
  }
})
4. 客户端消息
// 监听serviceWorker 消息
navigator.serviceWorker.addEventListener('message', function (event) {
    // 接受数据,
    console.log('页面接受的数据:',  event);
});
// 发送消息
document.getElementById('sendMSG').addEventListener('click', function () {
    console.log('绑定点击事件,点击后发送数据');
    navigator.serviceWorker.controller.postMessage('嘀嘀嘀');
});
5. 应用案例
1. 拦截图片加载失败 返回默认图片 案例 https://bitsofco.de/handling-broken-images-with-service-worker/
2. 蓝湖 https://lanhuapp.com/
### 新鲜货
1. https://github.com/jiahaog/nativefier#how-it-works  
3. https://imgcook.taobao.org/project

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

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

How to Design Programs, 2nd Edition

How to Design Programs, 2nd Edition

Matthias Felleisen、Robert Bruce Findler、Matthew Flatt、Shriram Krishnamurthi / MIT Press / 2018-5-4 / USD 57.00

A completely revised edition, offering new design recipes for interactive programs and support for images as plain values, testing, event-driven programming, and even distributed programming. This ......一起来看看 《How to Design Programs, 2nd Edition》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具