zoukankan      html  css  js  c++  java
  • service worker

    这是配置的sw.js

    已测试,是OK的.

    'use strict';
    
    const version = 'v2';
    const __DEVELOPMENT__ = false;
    const __DEBUG__ = true;
    const offlineResources = [
        './tt.html',
        './images/1.png',
        // '/imgerror.jpg',
        // '/favicon.ico'
    ];
    
    const ignoreCache = [
        /https?://hm.baidu.com//,
        /https?://www.google-analytics.com//,
        /http?://resource.haorooms.com//,
        /https?://www.haorooms.com/admin/,
        /https?://github.com//,
        // /https?://z4.cnzz.com//,
    ];
    
    // 慎重使用全局可变变量,因为 serviceWork 不可控的停止和重启,会导致它们的取值在后续读取时无法预测
    let port;
    
    
    /**
     * common function
     */
    
    function developmentMode() {
        return __DEVELOPMENT__ || __DEBUG__;
    }
    
    function cacheKey() {
        return [version, ...arguments].join(':');
    }
    
    function log() {
        if (developmentMode()) {
            console.log("SW:", ...arguments);
        }
    }
    
    // 不需要缓存的请求
    function shouldAlwaysFetch(request) {
        return __DEVELOPMENT__ ||
            request.method !== 'GET' ||
            ignoreCache.some(regex => request.url.match(regex));
    }
    
    // 缓存 html 页面
    function shouldFetchAndCache(request) {
        return (/text/html/i).test(request.headers.get('Accept'));
    }
    
    // 发送 Notification 通知
    function sendNotify(title, options, event) {
        if (Notification.permission !== 'granted') {
            log('Not granted Notification permission.');
    
            // 无授权时,向来源页面申请授权
            if (port && port.postMessage) {
                port.postMessage({
                    type: 'applyNotify',
                    info: {
                        title,
                        options
                    }
                });
            }
    
            return;
        }
    
        const notificationPromise = self.registration.showNotification(title || 'Hi:', Object.assign({
            body: '这是一个通知示例',
            icon: './images/1.png',
            requireInteraction: true,
            // tag: 'push'
        }, options));
    
        return event && event.waitUntil(notificationPromise);
    }
    
    /**
     * onClickNotify
     */
    
    function onClickNotify(event) {
        event.notification.close();
        const url = "https://www.baidu.com";
    
        event.waitUntil(
            self.clients.matchAll({
                type: "window"
            })
            .then(() => {
                if (self.clients.openWindow) {
                    return self.clients.openWindow(url);
                }
            })
        );
    }
    
    /**
     * Install 安装
     */
    
    function onInstall(event) {
        log('install event in progress.');
        event.waitUntil(
            caches.open(cacheKey('offline'))
            .then(cache => cache.addAll(offlineResources))
            .then(() => log('installation complete! version: ' + version))
            .then(() => self.skipWaiting())
        );
    }
    
    /**
     * Fetch
     */
    
    // 当网络离线或请求发生了错误,使用离线资源替代 request 请求
    function offlineResponse(request) {
        log('(offline)', request.method, request.url);
        if (request.url.match(/.(jpg|png|gif|svg|jpeg)(?.*)?$/)) {
            return caches.match('./imgerror.jpg');
        } else {
            return caches.match('./offline.html');
        }
    }
    
    // 从缓存读取或使用离线资源替代
    function cachedOrOffline(request) {
        return caches
            .match(request)
            .then((response) => response || offlineResponse(request));
    }
    
    // 从网络请求,并将请求成功的资源缓存
    function networkedAndCache(request) {
        return fetch(request)
            .then(response => {
                const copy = response.clone();
    
                caches.open(cacheKey('resources'))
                    .then(cache => {
                        cache.put(request, copy);
                    });
    
                log("(network: cache write)", request.method, request.url);
                return response;
            });
    }
    
    // 优先从 cache 读取,读取失败则从网络请求并缓存。网络请求也失败,则使用离线资源替代
    function cachedOrNetworked(request) {
        return caches.match(request)
            .then((response) => {
                log(response ? '(cached)' : '(network: cache miss)', request.method, request.url);
                return response ||
                    networkedAndCache(request)
                    .catch(() => offlineResponse(request));
            });
    }
    
    // 优先从网络请求,失败则使用离线资源替代
    function networkedOrOffline(request) {
        return fetch(request)
            .then(response => {
                log('(network)', request.method, request.url);
                return response;
            })
            .catch(() => offlineResponse(request));
    }
    
    function onFetch(event) {
        const request = event.request;
    
        // 应当永远从网络请求的资源
        // 如果请求失败,则使用离线资源替代
        if (shouldAlwaysFetch(request)) {
            log('AlwaysFetch request: ', event.request.url);
            event.respondWith(networkedOrOffline(request));
            return;
        }
    
        // 应当从网络请求并缓存的资源
        // 如果请求失败,则尝试从缓存读取,读取失败则使用离线资源替代
        if (shouldFetchAndCache(request)) {
            event.respondWith(
                networkedAndCache(request).catch(() => cachedOrOffline(request))
            );
            return;
        }
    
        event.respondWith(cachedOrNetworked(request));
    }
    
    /**
     * Activate
     */
    
    function removeOldCache() {
        return caches
            .keys()
            .then(keys =>
                Promise.all( // 等待所有旧的资源都清理完成
                    keys
                    .filter(key => !key.startsWith(version)) // 过滤不需要删除的资源
                    .map(key => caches.delete(key)) // 删除旧版本资源,返回为 Promise 对象
                )
            )
            .then(() => {
                log('removeOldCache completed.');
            });
    }
    
    function onActivate(event) {
        log('activate event in progress.');
        event.waitUntil(Promise.all([
            // 更新客户端
            self.clients.claim(),
            removeOldCache()
        ]))
    }
    
    /**
     * onPush
     */
    
    function onPush(event) {
        log('onPush ', event);
        sendNotify('Hi:', {
            body: `发生了一次 Push 同步事件 ~`
        }, event);
    }
    
    /**
     * onSync
     */
    
    function onSync(event) {
        log('onSync', event);
        sendNotify('Hi:', {
            body: `发生了一次 Sync 同步事件 ~`
        }, event);
    }
    
    /**
     * onMessage
     */
    
    function onMessage(event) {
        log('onMessage', event);
    
        if (event.ports) {
            port = event.ports[0];
        }
    
        if (!event.data) {
            return;
        }
    
        // 如果是要求一条通知,则发送
        if (event.data.type === 'notify') {
            const {
                title,
                options
            } = event.data.info || {};
            sendNotify(title, options, event);
        }
    }
    
    log("Hello from ServiceWorker land!", version);
    
    self.addEventListener('install', onInstall);
    self.addEventListener('fetch', onFetch);
    self.addEventListener("activate", onActivate);
    self.addEventListener("push", onPush);
    self.addEventListener("sync", onSync);
    self.addEventListener('message', onMessage);
    self.addEventListener("notificationclick", onClickNotify);
    

      

  • 相关阅读:
    背水一战 Windows 10 (90)
    背水一战 Windows 10 (89)
    背水一战 Windows 10 (88)
    背水一战 Windows 10 (87)
    背水一战 Windows 10 (86)
    背水一战 Windows 10 (85)
    背水一战 Windows 10 (84)
    背水一战 Windows 10 (83)
    背水一战 Windows 10 (82)
    背水一战 Windows 10 (81)
  • 原文地址:https://www.cnblogs.com/yiyi17/p/10975301.html
Copyright © 2011-2022 走看看