HTML5-service worker进行缓存控制

来源:互联网 发布:吉百利巧克力知乎 编辑:程序博客网 时间:2024/06/14 13:31

讲一下使用service worker做缓存版本控制。

1. 基础

生命周期

installing -> activated -> fech/message

需要关注的生命周期阶段

以下代码以使用indexedDB为例,后面提供使用service worker自带的cache的版本
install:首次缓存

self.addEventListener('install', function(e){    console.log('SW is installed');    e.waitUntil(        caches.open(CACHE_VERSION)            .then(function(cache){                const fetchInit = {method: 'GET'};                fetch('./JJ.mp3', fetchInit)                .then(function(response){                    response.arrayBuffer().then(function(buffer){                        indexedDB.set(buffer, 'Uh.mp3');                    });                });            }));});

activate:缓存版本更新

self.addEventListener('activate', function(e){    //Control your cache});

fetch:拦截请求

self.addEventListener('fetch', function(e){    console.log('Caught a fetch');    const url = new URL(e.request.url);    const fileName = url.split('/')[url.split('/').length-1];    console.log(fileName);    indexedDB.get(fileName, function(cacheData){        if(!cacheData){            console.log('No cache, sending a new request......');            fetch(e.request)                .then(function(response){                    response.arrayBuffer().then(function(buffer){                        indexedDB.set(arrayBuffer, fileName);                        console.log('Cache the file successfully');                    });                });        }else{            const cacheResponse = new Response(cacheData);            e.respondWith(cacheResponse);        }    });});

下面代码使用service worker自带的cache,这些数据会存到浏览器cache storage里,使用chrome可以从 Application -> Cache -> Cache Storage中看到

var CACHE_VERSION = 'V1';var fileURLs = ['https://wximg.gtimg.com/lightmap/cacheTest/ding.mp3'];console.log('SW is working......');self.addEventListener('install', function(e){    console.log('SW is installed');    e.waitUntil(        caches.open(CACHE_VERSION)            .then(function(cache){                return cache.addAll(fileURLs);                })            );});self.addEventListener('activate', function(e){    //control your cache    event.waitUntil(caches.keys().then(function(cacheNames) {        return Promise.all(cacheNames.map(function(cacheName) {            if (cacheName != (SW_VERSION)) {                return caches.delete(cacheName);            }        }));    }));});self.addEventListener('fetch', function(e){    //console.log(e.request);    console.log('Catch a fetch event');    var sourceType = e.request.url.split('.')[e.request.url.split('.').length-1].toLowerCase();    if(sourceType === 'mp3'){         e.respondWith(caches.match(e.request).then(function(response){            if(response){                return response;            }else{                fetch(e.request).then(function(response){                    caches.open(CACHE_VERSION).then(function(cache){                        cache.put(e.request, response.clone());                    }).then(function(){                        return response;                    });                });            }        }));    }else{        console.log('Fetched file is not mp3', sourceType);    }});

3)业务逻辑
用service控制缓存数据(可以用indexedDB或者直接使用service worker自带的cache),install时存入需要静态缓存的数据,fetch时根据url判断数据库中是否有该条数据,决定是发送请求还是直接返回数据库中数据,activate中指定更新策略

2. service worker中遇到的问题

数据库中已经缓存了数据,但是fetch事件不响应,拦截请求不成功

这里写图片描述

一开始以为是fetch()不会触发fetch事件,但是查到:
这里写图片描述

那应该是可以触发fetch event的。

然后以为是chrome的bug,不支持fetch事件,因为用window监听fetch事件也不响应。然而firefox也不响应。。。

最后定位问题在于,service worker中,只监听它所控制的scope。我的service worker控制的域是:http://localhost:8080/src/audioCache/,但是发出请求的域是http://localhost:8080/,所以监听不到啊,但是由于文件目录层级原因,我的worker最多只能监听到http://localhost:8080/src/audioCache/。发出请求的域和worker最多可以监听的域不同的原因是,我用webpack启的server,webpack会打包出两个文件,都直接引入index.html中,但是service worker是在一个单独环境运行的啊,它是web worker的一种啊。。。不会被打包啊。。。
这里写图片描述
然而service worker必须在localhost或者https下运行,我必须有一个server,webpack不行的话,我只能用node或者php启动一服务。后来使用php+apache测试成功。

参考链接
https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API/Using_Service_Workers
https://gist.github.com/inexorabletash/687e7c5914049536f5a3
https://github.com/w3c/ServiceWorker/blob/master/explainer.md
http://w3c.github.io/push-api/
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

0 0
原创粉丝点击