How to apply CORS preflight cache to an entire domain

I am building a REST application that makes use of CORS. Every REST call is different and I am finding that there is significant overhead in getting the preflight OPTIONS call. Is there a way to cache and apply a preflight OPTIONS result so that any subsequent calls to the same domain use the cached response?

30727 次浏览

Preflight can only be applied to the request, not to the entire domain. I brought the same question up on the mailing list, and there were security concerns. Here's the entire thread: http://lists.w3.org/Archives/Public/public-webapps/2012AprJun/0228.html

There are a few things to consider if you'd like to limit the number of preflight requests. First note that WebKit-based browsers set a max preflight cache lifetime of 10 minutes:

https://github.com/WebKit/webkit/blob/master/Source/WebCore/loader/CrossOriginPreflightResultCache.cpp and Blink-based browsers limit the cache to two hours: https://source.chromium.org/chromium/chromium/src/+/main:services/network/cors/preflight_result.cc;l=40;drc=098756533733ea50b2dcb1c40d9a9e18d49febbe

(I'm not sure if this is true for other browsers). So while you should always set the Access-Control-Max-Age header.

Next note that it is impossible to avoid a preflight on PUT/DELETE requests. So updates/deletes to your API will require at least one preflight every 10 minutes.

On GET/POST, avoid custom headers if at all possible, since these still trigger preflights. If your API returns JSON, note that a Content-Type of 'application/json' also triggers a preflight.

If you are willing to bend just how "RESTful" your API is, there are a few more things you can try. One is to use a Content-Type that doesn't need a preflight, like 'text/plain'. Custom headers always trigger preflights, so if you have any custom headers, you could move them into query parameters. At the extreme end, you could use a protocol like JSON-RPC, where all requests are made to a single endpoint.

In all honesty, because of the browser's preflight cache limit of 10/120 minutes, and REST's resource urls, the preflight cache is of limited value. There's very little you can do to limit preflights over the course of a long running app. I'm hopeful the authors of the CORS spec will try to address this in the future.

Try using xDomain

It was pretty simple for me to setup if using angular or jQuery. On your app server, add a proxy.html as stated in the help on the below link. Add some tags referring to the js files on your "client" and viola, no more pre-flights. This wraps in an iframe to avoid need for cors check.

https://github.com/jpillora/xdomain

One way is that you can point all your API calls to same domain as your front-end. Setup nginx on the front-end server to forward only API calls to API server. This will remove all pre-flight calls.