sw.js 3.82 KB
/* eslint-env worker */
var config = {
    customCacheDomain: [
        'cdn.yoho.cn',
        'static.yhbimg.com'
    ],
    precacheStaticFile: [
        '/index.css',
        '/common.css',
        '/libs.js'
    ],
    precacheFile: [{
        url: 'https://cdn.yoho.cn/pwa/workbox-sw.prod.v2.1.2.js'
    }]
};
var utils = {
    iSInCustomCacheDomain: function(domain) {
        var isIn = false;

        config.customCacheDomain.forEach(function(d) {
            if (domain.indexOf(d) >= 0) {
                isIn = true;
            }
        });

        return isIn;
    },

    parseQs: function(str) {
        var vars = {},
            hashes,
            hash,
            i;

        str = str || '';

        if (str) {
            hashes = str.split('&');
            for (i = 0; i < hashes.length; i++) {
                hash = hashes[i].split('=');
                vars[hash[0]] = hash[1];
            }
        }
        return vars;
    }
};
var qs = utils.parseQs(self.location.search.substr(1));
var workboxSW;

// 加载 workbox,后边看下怎么好好利用
importScripts('https://cdn.yoho.cn/pwa/workbox-sw.prod.v2.1.2.js');

// WorkboxSW
workboxSW = new self.WorkboxSW({
    clientsClaim: true,
    skipWaiting: true
});

// 特殊路径的预缓存文件文件
config.precacheFile = config.precacheFile.concat([{
    url: '/sw.js?t=' + qs.t + '&staticServer=' + qs.staticServer
}]).concat(config.precacheStaticFile.map(function(file) {
    // 根据业务自定义资源路径
    var url = self.location.protocol + qs.staticServer + file + '?t=' + qs.t;

    return {
        url: url
    };
}));

// 初始化

workboxSW.precache(config.precacheFile);

self.addEventListener('install', function(event) {
    console.log('install', event);

    // event.waitUntil(
    //     caches.open('common-cache').then(function(cache) {
    //         return cache.addAll([
    //             '/'
    //         ]);
    //     })
    // );
});

self.addEventListener('error', function(event) {
    console.error('error', event);

    // 上报错误信息
    // 常用的属性:
    // event.message
    // event.filename
    // event.lineno
    // event.colno
    // event.error.stack
});

self.addEventListener('unhandledrejection', function(event) {
    console.error('unhandledrejection', event);

    // 上报错误信息
    // 常用的属性:
    // event.reason
});

self.addEventListener('fetch', function(event) {
    var domain = event.request.url.split('/')[2];
    var shouldCache = utils.iSInCustomCacheDomain(domain);

    // 使用域名白名单进行缓存
    if (shouldCache) {
        event.respondWith(
            caches.match(event.request).then(function(response) {
                var request = event.request.clone(); // 把原始请求拷过来

                // 如果 Service Worker 有自己的返回,就直接返回,减少一次 http 请求
                if (response) {
                    return response;
                }

                // 如果 service worker 没有返回,那就得直接请求真实远程服务
                return fetch(request, {
                    mode: 'cors',
                    credentials: 'same-origin'
                }).then(function(httpRes) {
                    var httpResClone = httpRes.clone();

                    // 请求失败了,直接返回失败的结果就好了。。
                    if (!httpRes || httpRes.status !== 200) {
                        return httpRes;
                    }

                    // 请求成功的话,将请求缓存起来。
                    caches.open('custom-cache').then(function(cache) {
                        cache.put(event.request, httpResClone);
                    });

                    return httpRes;
                });
            }).catch(function(err) {
                console.log(err);
            })
        );
    }
});