27

I'm experiencing an issue with Chrome that I can't seem to fully understand, I'm curious if folks here have dealt with it before. This doesn't reproduce in Firefox. The steps are as follows:

  1. Start incognito Chrome, navigate to https://foo.mysite.com and have the JS on the page make a GET ajax request to S3 for https://s3.amazonaws.com/mystuff/file.json . You get back a 200 response with:

    HTTP/1.1 200 OK
    x-amz-id-2: somestuffhere
    x-amz-request-id: somestuffhere
    Date: Tue, 14 Oct 2014 03:06:41 GMT
    Access-Control-Allow-Origin: https://foo.mysite.com
    Access-Control-Allow-Methods: GET
    Access-Control-Max-Age: 3000
    Access-Control-Allow-Credentials: true
    Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
    Cache-Control: max-age=86400
    Content-Encoding: gzip
    Last-Modified: Sun, 05 Oct 2014 00:29:53 GMT
    ETag: "fe76607baa40a793eb3b3cbd373a3fb8"
    Accept-Ranges: bytes
    Content-Type: application/json
    Content-Length: 5609
    Server: AmazonS3
    
  2. Open a second tab, navigate to https://bar.mysite.com and have its JS make a GET ajax request to S3 for the same file https://s3.amazonaws.com/mystuff/file.json . Get back the following 304 response:

    HTTP/1.1 304 Not Modified
    x-amz-id-2: somestuffhere
    x-amz-request-id: somestuffhere
    Date: Tue, 14 Oct 2014 03:06:58 GMT
    Access-Control-Allow-Origin: https://bar.mysite.com
    Access-Control-Allow-Methods: GET
    Access-Control-Max-Age: 3000
    Access-Control-Allow-Credentials: true
    Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
    Cache-Control: max-age=86400
    Last-Modified: Sun, 05 Oct 2014 00:29:53 GMT
    ETag: "fe76607baa40a793eb3b3cbd373a3fb8"
    Server: AmazonS3
    
  3. Open a third tab, navigate to https://foo.mysite.com (the first site) and repeat the same steps as in 1. Chrome kills the response for CORS reasons and reports the following:

    XMLHttpRequest cannot load https://s3.amazonaws.com/mystuff/file.json. The 'Access-Control-Allow-Origin' header has a value 'https://bar.mysite.com' that is not equal to the supplied origin. Origin 'https://foo.mysite.com' is therefore not allowed access.
    

What's the story here? This doesn't reproduce in Firefox. In Firefox I'm happily getting a 304 in both steps 2 and 3, which I would expect to see in Chrome as well.

A temporary workaround for this issue in Chrome is to set Cache-Control: no-cache on the file in S3, but then I'm forcing our clients to be re-downloading that file for no good reason, so it's not a real solution.

Is this intended and documented behavior? Is this a bug with Chrome? Any other thoughts?

Alexandr Kurilin
  • 7,685
  • 6
  • 48
  • 76
  • This sounds like a proxy caching issue, except that the `Vary` header is set on the response, which should prevent the proxy caching issue. Can you inspect and share the response headers on response #3 (the failing response)? – monsur Oct 14 '14 at 15:10
  • The request is never received from the server because Chrome cancels the request. It shows provisional request headers and best, and those aren't super helpful. I tried to see if perhaps capturing through chrome://net-internals would have led to seeing the response, but it also never makes it past the request there. – Alexandr Kurilin Oct 14 '14 at 17:27
  • s/request/response/ in the first sentence above. – Alexandr Kurilin Oct 14 '14 at 17:35
  • Cannot reproduce in Chromium 38.0.2125.106 (using netcat). Could you provide a demo page and website? – Rob W Oct 28 '14 at 10:52

3 Answers3

3

Looks like this is caused by Chromium issue 260239

Alexandr Kurilin
  • 7,685
  • 6
  • 48
  • 76
3

I found this blog that help: Add Vary headers to S3 It helped by adding Vary headers to all XHR request.

I did run into a problem with html request (i.e. ) but I was able to overcome that by using hackround#2 described here:https://serverfault.com/a/856948

TL;DR of hack#2 is to use a "dummy" query string parameter that differs for HTML and XHR or is absent from one or the other. Example: <img src="https://s3.png?x-request=html">

1

I just add a timestamp in request URL to force load the asset from S3 again, not from cache, such as xxxx?timestamp=yyyy

Yuri
  • 4,254
  • 1
  • 29
  • 46
ramon.liu
  • 186
  • 3
  • 5
  • what if the request url is `https://{bucket-name}.s3.amazonaws.com/` and used as a form action, will this also work? – Abel Callejo Aug 20 '15 at 07:45