代码之家  ›  专栏  ›  技术社区  ›  Amit Merchant

ServiceWorker阻止任何外部资源

  •  0
  • Amit Merchant  · 技术社区  · 6 年前

    我已经实现了 ServiceWorker 在我的一些webapps上利用离线功能和其他一些与serviceworks相关的功能。现在,一切正常,直到我添加了一些外部嵌入脚本。我在我的webapp上添加了大约3个外部脚本。其中一些是获取广告并显示在我的应用程序上,还有一些是用来收集分析。

    但是,令我惊讶的是,当ServiceWorker被启用时,每个外部脚本都会失败,并在控制台中抛出以下错误

    enter image description here

    我不知道为什么会这样?我需要在ServiceWorker中以某种方式缓存这些脚本吗?任何帮助都将不胜感激。

    这是我在应用程序中添加的ServiceWorker代码。

    importScripts('js/cache-polyfill.js');
    
    var CACHE_VERSION = 'app-v18';
    var CACHE_FILES = [
        '/',
        'index.html',
        'js/app.js',
        'js/jquery.min.js',
        'js/bootstrap.min.js',
        'css/bootstrap.min.css',
        'css/style.css',
        'favicon.ico',
        'manifest.json',
        'img/icon-48.png',
        'img/icon-96.png',
        'img/icon-144.png',
        'img/icon-196.png'
    ];
    
    self.addEventListener('install', function (event) {
        event.waitUntil(
            caches.open(CACHE_VERSION)
                .then(function (cache) {
                    console.log('Opened cache');
                    return cache.addAll(CACHE_FILES);
                })
        );
    });
    
    self.addEventListener('fetch', function (event) {
        event.respondWith(
            caches.match(event.request).then(function(res){
                if(res){
                    return res;
                }
                requestBackend(event);
            })
        )
    });
    
    function requestBackend(event){
        var url = event.request.clone();
        return fetch(url).then(function(res){
            //if not a valid response send the error
            if(!res || res.status !== 200 || res.type !== 'basic'){
                return res;
            }
    
            var response = res.clone();
    
            caches.open(CACHE_VERSION).then(function(cache){
                cache.put(event.request, response);
            });
    
            return res;
        })
    }
    
    self.addEventListener('activate', function (event) {
        event.waitUntil(
            caches.keys().then(function(keys){
                return Promise.all(keys.map(function(key, i){
                    if(key !== CACHE_VERSION){
                        return caches.delete(keys[i]);
                    }
                }))
            })
        )
    });
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Amit Merchant    6 年前

    以下是我为解决这个问题所做的。

    我试着检查应用程序是否在线 Navigator.onLine 中的API fetch 如果事件侦听器处于联机状态,则从服务器和 ServiceWorker 否则。这样,应用程序联机时请求不会被阻止,从而解决了此特定问题。

    下面是我如何实现它的。

    self.addEventListener('fetch', function (event) {
        let online = navigator.onLine;
        if(!online){
          event.respondWith(
              caches.match(event.request).then(function(res){
                  if(res){
                      return res;
                  }
                  requestBackend(event);
              })
          )
        }
    });
    

    您还可以在此处检查整个ServiceWorker脚本: https://github.com/amitmerchant1990/notepad/blob/master/sw.js