sw.js 3.64 KB
/* eslint-env worker */
importScripts('https://cdn.yoho.cn/pwa/workbox-sw.prod.v2.1.2.js');

// 不得已写 es5 的代码,忽略 var
/* eslint-disable vars-on-top */
var precacheStaticFile = [
    '/index.css',
    '/common.css',
    '/libs.js',
    '/channel.index.js'
];
var customCacheDomain = [
    'cdn.yoho.cn',
    'static.yhbimg.com'
];

// 工具函数
function iSInCustomCacheDomain(domain) {
    var isIn = false;

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

    return isIn;
}

function parseQs(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 = parseQs(self.location.search.substr(1));

// WorkboxSW
var workboxSW = new self.WorkboxSW({
    clientsClaim: true,
    skipWaiting: true
});
var precacheFile = [
    {
        url: '/sw.js?t=' + qs.t + '&staticServer=' + qs.staticServer
    },
    {
        url: 'https://cdn.yoho.cn/pwa/workbox-sw.prod.v2.1.2.js'
    },
    {
        url: '/'
    }
];

precacheFile = precacheFile.concat(precacheStaticFile.map(function(file) {
    // 根据业务自定义资源路径
    var url = self.location.protocol + qs.staticServer + file + '?t=' + qs.t;

    return {
        url: url
    };
}));

workboxSW.precache(precacheFile);

// self.addEventListener('install', function(event) {
//     event.waitUntil(
//         caches.open('common-cache').then(function(cache) {
//             return cache.addAll([
//                 'https://devcdn.yoho.cn:7001/index.css'
//             ]);
//         })
//     );
// });

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

    // 上报错误信息
    // 常用的属性:
    // event.message
    // event.filename
    // event.lineno
    // event.colno
    // event.error.stack
});
self.addEventListener('unhandledrejection', event => {
    console.error('unhandledrejection', event);

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

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

    // 使用域名白名单进行缓存
    if (shouldCache) {
        event.respondWith(
            caches.match(event.request).then(function(response) {
                // 如果 Service Worker 有自己的返回,就直接返回,减少一次 http 请求
                if (response) {
                    return response;
                }

                // 如果 service worker 没有返回,那就得直接请求真实远程服务
                let request = event.request.clone(); // 把原始请求拷过来

                return fetch(request, {
                    mode: 'cors',
                    credentials: 'same-origin'
                }).then(function(httpRes) {
                    // 请求失败了,直接返回失败的结果就好了。。
                    if (!httpRes || httpRes.status !== 200) {
                        return httpRes;
                    }

                    // 请求成功的话,将请求缓存起来。
                    var responseClone = httpRes.clone();

                    caches.open('custom-cache').then(function(cache) {
                        cache.put(event.request, responseClone);
                    });

                    return httpRes;
                }).catch(console.error);
            })
        );
    }
});

/* eslint-enable vars-on-top */