如何使用我的服务工作者处理AWS s3产生的非CORS污染浏览器缓存?

时间:2016-12-13 23:42:32

标签: javascript amazon-s3 cors service-worker

我的公司有许多应用程序请求共享资源存在于AWS S3上。其中一些应用程序使用crossorigin="anonymous" html元素,有些则不然。 AWS不会发回CORS响应标头,例如“Allow-access-control-origin”,when there is no Origin request header。因此,一些用户可以使用没有CORS响应头的文件的broswer缓存版本。

当这些用户访问我团队的应用程序时,Service Worker可能无法请求这些共享资产,因为浏览器磁盘缓存以非cors方式使用它们。错误如下所示:

  

请求的资源上没有“Access-Control-Allow-Origin”标头。因此,不允许原点“http://localhost:8001”访问。如果不透明响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用CORS的资源。

当然,我不能使用不透明的响应进行可靠的缓存。

我想我可以应用缓存控制请求标头来绕过浏览器缓存,但是Fetch API Request is immutable的Headers对象。因此,我无法将标头添加到现有请求中。如果我尝试创建新请求,则无法从AWS获得CORS响应,因为我无法在Fetch API中设置Origin is a forbidden header

如果出现以下问题,将解决此问题:

  • 我可以强制执行公司中的所有团队,以确保他们使用crossorigin html属性,但我不能。

  • 我可以让AWS始终使用CORS标头进行响应,但我不能。

  • 使用和Origin标头创建获取请求,但我不能。

  • 说服我的组织设置不允许浏览器缓存资产的缓存控制标头,但这是一个坏主意。

我能做些什么来克服这个问题吗?现在,我只是禁用这些共享资产上的Service Worker缓存,以避免网络故障。

3 个答案:

答案 0 :(得分:2)

你说如果你能使用Origin标头创建一个获取请求,你的问题就会解决,但我不能。

您应该可以通过构建自己的Request并明确将mode设置为'cors'来实现这一目标。这是一个例子:



const failingRequest = new Request('https://example.com', {
  mode: 'cors'
});
fetch(failingRequest).then(console.log).catch(console.warn);

const successfulRequest = new Request('https://cors-test.appspot.com/test', {
  mode: 'cors'
});
fetch(successfulRequest).then(console.log).catch(console.warn);




您应该看到启用了CORS的请求同时发送到https://example.comhttps://cors-test.appspot.com/test。第一个请求将失败,因为服务器不支持CORS,而第二个请求将成功并使用非透明的Response对象解析。

答案 1 :(得分:1)

看起来我们想要更好地控制我们的服务工作者如何处理缓存,例如Firefox中提供的新缓存选项:https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/ 这是在https://bugs.chromium.org/p/chromium/issues/detail?id=453190

实施的现有Chromium问题

理想情况下,我们会做这样的事情:

  // Download a resource with cache busting, to bypass the cache
  // completely.
  fetch("some.json", {cache: "no-store"}) // or "reload"
    .then(function(response) { /* consume the response */ });

答案 2 :(得分:0)

我想我只是让我的应用程序请求所有这些共享资产以及特定于我的应用程序的查询字符串。感觉不对,但应该有用。

编辑 - 感谢杰夫,我不必做浏览器缓存破坏。当服务人员需要资产时,我总是可以通过网络。这就是我正在做的,它可以产生一个避免浏览器磁盘缓存的CORS请求:

function respondWithCacheOrNetwork(event) {
  var headers = new Headers();
  event.request.headers.forEach((v, k) => { headers.set(k, v); });
  // Copy the old headers, cannot modify because immutable
  headers.set('cache-control', 'no-cache');
  var skipBrowserCacheRequest = new Request(event.request.url,
    {
      mode: 'cors',
      method: event.request.method,
      headers: headers
    }
  );
    event.respondWith(toolbox.cacheFirst(skipBrowserCacheRequest));
}