37

I'm hosting an WebApp and his API on different domains and use CORS to be able to work around the same origin policy. So far, so good. This works.

To only send a CORS preflight once per session I set the Access-Control-Max-Age to 20 days, But this is not working (tested in Chrome): https://db.tt/vfIW3fD2

What do I have to change?

Roland Schütz
  • 812
  • 2
  • 8
  • 21

3 Answers3

118

If you are using Chrome Dev Tools, make sure you have "Disable cache (while DevTools is open)" unchecked. I was having issues with the "Access-Control-Max-Age" not being honored only to realize that I had that option checked.

Nej Kutcharian
  • 4,054
  • 5
  • 21
  • 27
25

Chrome/Blink imposes a max preflight time of 10 minutes (600 seconds). Here's the location in source code that defines this:

https://chromium.googlesource.com/chromium/blink/+/master/Source/core/loader/CrossOriginPreflightResultCache.cpp#40

Any preflight time above 10 minutes will be ignored, and 10 minutes will be used instead.

Different browsers may have different max age policies. Safari/WebKit caches for up to 5 minutes, while Firefox caches for up to 24 hours. The Chrome source code indicates that the max value exists in order to "minimize the risk of using a poisoned cache after switching to a secure network".

If the code can't parse the max-age header (or the server doesn't specify a max-age header), the browser defaults to 5 seconds.

Iso
  • 3,148
  • 23
  • 31
monsur
  • 45,581
  • 16
  • 101
  • 95
  • 1
    Hello, thanks for the explanation. This still doesn't explain why the preflight is done again after 5 seconds. Any ideas – Roland Schütz May 08 '14 at 19:41
  • I updated the answer with a section about when the 5 second timeout is chosen. But in your particular case, the timeout should be 5 minutes and not 5 seconds, since your max-age header looks valid. The only other thing it could be is what +Ray Nicholus mentions above (the headers or origins don't match). Can you recreate this on test-cors.org? – monsur May 09 '14 at 02:04
  • I can't recreate the issue with test-cors.org, since the problem occurs in the second request. Here are my request and response, which should (but doesn't) lead to a cached OPTIONS request. https://gist.github.com/rolandschuetz/cd278a9489b5065a256d – Roland Schütz May 14 '14 at 14:36
  • 2
    After 2 years and chrome still is ignoring cache :(... Tested on 54.0.2840.50 beta (64-bit) – LiberQuack Oct 07 '16 at 04:04
10

I wouldn't rely too heavily on preflight caching.

From the spec:

User agents may clear cache entries before the time specified in the max-age field has passed.

Also, keep the following in mind, (from the CORS spec):

There is a cache match when there is a cache entry in the preflight result cache for which the following is true:

The origin field value is a case-sensitive match for source origin.

The url field value is a case-sensitive match for request URL.

The credentials field value is true and the omit credentials flag is unset, or it is false and the omit credentials flag is set.

Your screenshot does not provide a way to determine if any of the above are true.

Community
  • 1
  • 1
Ray Nicholus
  • 19,538
  • 14
  • 59
  • 82
  • Hello! First two yes, where is the third one? Here's the corresponding HAR: https://gist.github.com/rolandschuetz/cd278a9489b5065a256d – Roland Schütz May 08 '14 at 15:09
  • The omit credentials flag is set if `withCredentials` on the XHR instance !== true. The credentials field value refers to the Access-Control-Allow-Credentials header that may or may not be present in the server response. In other words, it sounds like the preflight cache will not be consulted if an otherwise similar preflight request was sent and cached, but the match in the preflight cache did include cookies but not an Access-Control-Allow-Credentials=true in the response, or did not include cookies in the request but did include an Access-Control-Allow-Credentials=true in the response. – Ray Nicholus May 14 '14 at 14:48
  • ...not 100% certain of my understanding, but I don't have a better interpretation. Maybe @monsur can refute or confirm my understanding... – Ray Nicholus May 14 '14 at 14:48
  • I think I understand the concept. I'll try if that helps. Thanks – Roland Schütz May 14 '14 at 20:50