Anne van Kesteren

Preflight result cache

Today I updated the cache policy for preflight requests in the Access Control for Cross-Site Requests specification. Eventually it turned out to be fairly simple, but wrapping my head around it and considering all the cases somehow always requires considerable effort. Authors will be glad to learn that this is all transparent to them. Implementors tell me it’s understandable, but then nobody evil (e.g. Ian or Simon) has tested their implementations yet.

The preflight result cache stores the result of a preflight request, which is transparent from the Web API point of view (e.g. XMLHttpRequest), but does require server deployment. Previously a cache entry stored the origin of the request (e.g.,,, are all different origins), the request URL, an expiry time, and the methods and headers allowed (as indicated by response headers). (And the value of the credentials flag, but it is already complicated enough. Hah!) This model was reasonably simple, but it did not really allow for adding new headers and methods over time, as those might have different expiry times. The change the new model made was having a single entry per allowed header or method avoiding that problem. Though everything else had to be updated to take that into account.

In the Web developer world all aforementioned details are not important. It is important that implementors get them right so your servers stay secure (if they are) and you have a reliable platform. All authors have to do to make resources available from other origins is using the Access-Control-Allow-Origin header. And for slightly more complicated scenarios (e.g., a request using the DELETE method coming from another origin) you need to reply to a preflight request which uses the OPTIONS method with a set of additional headers indicating what headers and methods (indeed, DELETE) you allow. Enlightened, yet?