2017-11-30 3 views
0

serviceworker 파일 캐싱을 구현해야하지만 no-cors 플래그를 사용해야합니다. 아래 코드에 대한 웹 서버에서 CORS 오류가 발생했기 때문입니다. 이 코드는 표준 Ionic 2 시작 템플릿 (serviceworker.js 내부)에서 가져온 것입니다. 어떤 이유로 CORS 오류로 인해 실패하는 URL로 리디렉션되는 요청이 인증 흐름을 트리거하기 때문에 표준 코드를 사용할 수 없습니다.Ionic PWA serviceworker - no CORS

내가 가장 좋은 (cq. 가장 쉬운) 방법으로 어떻게 할 수 있습니까?

// TODO: Implement this without CORS (set no-cors flag) 
self.toolbox.precache(
    [ 
    // './build/main.js', 
    // './build/vendor.js', 
    // './build/main.css', 
    // './build/polyfills.js', 
    // 'index.html', 
    // 'manifest.json' 
    ] 
); 

EDIT : 실제로 인증 오류가 아니며 사용자는 이미 인증되었습니다. 그러나 인증 도중 리디렉션 때문에 위 파일에 대한 요청이 잘못됩니다. 이 기사에서는 What is an opaque request, and what it serves for?으로 설정되어 있음을 나타내며 no cors 플래그가 해결책이됩니다. 해당 페이지에서와 같은 오류는 다음과 같습니다. 'Access-Control-Allow-Origin'헤더가 요청 된 리소스에 없습니다. 오리진 'http://abc'은 액세스 할 수 없습니다. 불투명 한 응답이 사용자의 요구에 부합하는 경우 요청 모드를 'no-cors' 으로 설정하여 CORS를 비활성화 한 상태에서 리소스를 가져옵니다.

+0

확실히 no-cors 플래그를 설정하면 인증 오류가 발생하여 모든 것이 중지됩니다. – Quentin

답변

0

다음과 같이 직접 해결했습니다. 설치 이벤트는 앱이 파일을 로컬에 저장하도록 유도하는 것입니다.

/** 
* Check out https://googlechromelabs.github.io/sw-toolbox/ for 
* more info on how to use sw-toolbox to custom configure your service worker. 
*/ 


'use strict'; 
importScripts('./build/sw-toolbox.js'); 

self.toolbox.options.cache = { 
    name: 'ionic-cache' 
}; 

// pre-cache our key assets 
// TODO: Implemente this without using CORS (set no-cors flag) 
/* 
self.toolbox.precache(
    [ 
    './build/main.js', 
    './build/vendor.js', 
    './build/main.css', 
    './build/polyfills.js', 
    'index.html', 
    'manifest.json' 
    ] 
); 
*/ 

// MANUAL precaching in order to evade CORS error on SharePoint 

var aFilesToCache = [ 
    './assets/json/propertyLUT.js', 
    './assets/json/propertyvalues.js', 
    './build/main.js', 
    './build/vendor.js', 
    './build/main.css', 
    './build/polyfills.js', 
    'index.html', 
    'manifest.json' 
]; 

self.addEventListener('fetch', function(event) { 
    console.log('Handling fetch event for', event.request.url); 

    event.respondWith(

    // Opens Cache objects that start with 'font'. 
    caches.open('pwa_').then(function(cache) { 
     return cache.match(event.request).then(function(response) { 
     if (response) { 
      console.log('Found response in cache:', response); 

      return response; 
     } 
     }).catch(function(error) { 

     // Handles exceptions that arise from match() or fetch(). 
     console.error('Error in fetch handler:', error); 

     throw error; 
     }); 
    }) 
); 
}); 

self.addEventListener('install', event => { 
    function onInstall(event, filesToCache) { 
    console.log('Hit event INSTALL'); 
    return Promise.all(filesToCache.map(function(aUrl) 
    { 
     return caches.open('pwa_').then(function(cache) 
     { 
     debugger; 
     aUrl = resolveURL(aUrl, self.location.href); 
     return fetch(aUrl, { mode: 'no-cors' }) 
      .then(function(response) 
      { 
       return cache.put(aUrl, response.clone()); 
      }); 

     }) 
    })) 
    } 

    event.waitUntil(
    onInstall(event, aFilesToCache).then(() => self.skipWaiting()) 
); 
}); 

function resolveURL(relative, base) { 
    var stack = base.split("/"), 
     parts = relative.split("/"); 
    stack.pop(); // remove current file name (or empty string) 
       // (omit if "base" is the current folder without trailing slash) 
    for (var i=0; i<parts.length; i++) { 
     if (parts[i] == ".") 
      continue; 
     if (parts[i] == "..") 
      stack.pop(); 
     else 
      stack.push(parts[i]); 
    } 
    return stack.join("/"); 
} 
/* 
foreach(aUrl in aFilesToCache) 
{ 
    var corsRequest = new Request(url, {mode: 'no-cors'}); 
    fetch(corsRequest).then(response => { 
    return cache.put("pwa_" + url, response); 
    }); // response won't be opaque. 
} 
*/ 

// dynamically cache any other local assets 
self.toolbox.router.any('/*', self.toolbox.fastest); 

// for any other requests go to the network, cache, 
// and then only use that cached resource if your user goes offline 
self.toolbox.router.default = self.toolbox.networkFirst;