I am making CORS request to a web service using jQuery $.ajax
. As per standard there is a pre-flight request and then the actual POST request.
What I have noticed is, there are two requests everytime I try to make a web service call (one pre-flight and one actual POST request) only If there is a time interval between the two requests.
If I keep making the web service call successively without any time gap (like less than 1 second between two requests) then the pre-flight is missing.
How can I avoid this pre-flight request every time?
What is this time interval?
Is this something specific to Chrome browser?
There are differences between browsers in how they implement pre-flight caching. Unfortunately the W3C spec alone does not explain the nuances you've observed in pre-flight caching.
For others reading this question, I'd like to explain when the OP says pre-flight request he is referring to the OPTIONS
request that precedes a cross-origin POST
request. The OPTIONS
request is used to query an API and determine which HTTP methods are permissible for cross-origin requests. Typically, you'd expect to see this type of response to an OPTIONS
request:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, X-Requested-With
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Since you are working with Google Chrome, I will refer you to the applicable section of the Webkit source code:
https://github.com/WebKit/webkit/blob/master/Source/WebCore/loader/CrossOriginPreflightResultCache.cpp
The default pre-flight cache timeout is 5 seconds:
static const auto defaultPreflightCacheTimeout = std::chrono::seconds(5);
The maximum value is 5 minutes:
static const auto maxPreflightCacheTimeout = std::chrono::seconds(600);
The server can specify a timeout value for pre-flight requests using the Access-Control-Max-Age
field in the response header, however the Webkit browser enforces a maximum timeout of 5 minutes.
To answer your questions:
How can I avoid this pre flight request every time?
You need to set Access-Control-Max-Age
to 600 in the header of your API response to the OPTIONS
request.
What is this time interval?
For Webkit browsers (i.e., Google Chrome) the default timeout value is 5 seconds. That is why you are seeing the pre-flight request before each POST request, but if you rapidly submit POST requests, then you do not see additional pre-flight requests.
Is this something specific to Chrome browser?
Yes, there are differences between browsers in how pre-flight caching is implemented. The W3C spec does not specify everything needed to build out pre-flight caching functionality in a web browser.
The browser will not make a preflight request if the following two situations are true:
- For request method there either is a method cache match or it is a simple method and the force preflight flag is unset.
- For every header of author request headers there either is a header cache match for the field name or it is a simple header.
This reference shows the user agent (browser) responsibilities with CORS: http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
Otherwise, you should not worry over it. The browser implementation will do the right thing.