我需要实现serviceworker文件缓存,但使用no-cors标志。 这是因为我在我的网络服务器上收到以下代码的CORS错误。代码来自标准的Ionic 2入门模板(在serviceworker.js内部)。我无法使用标准代码,因为由于某种原因,请求会触发一个身份验证流,其中有一个重定向到某个URL,由于CORS错误而失败。
我如何以最好的(最简单的方式)做到这一点?
// 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'
]
);
编辑:这不是真正的身份验证错误,用户肯定已经过身份验证。但由于验证过程中的重定向,上述文件的请求出错。我发现这篇文章:What is an opaque request, and what it serves for?表示设置no cors标志将是解决方案。我得到的错误,如在该页面上是: 请求的资源上不存在“Access-Control-Allow-Origin”标头。 因此,不允许原点“http://abc”访问。 如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors” 在禁用CORS的情况下获取资源。
答案 0 :(得分: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;