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?
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.
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.
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.