Why is an OPTIONS request sent and can I disable it?

Qian Chen picture Qian Chen · Apr 29, 2015 · Viewed 437.9k times · Source

I am building a web API. I found whenever I use Chrome to POST, GET to my API, there is always an OPTIONS request sent before the real request, which is quite annoying. Currently I get the server to ignore any OPTIONS requests. Now my questions is what's good to send an OPTIONS request to double the server's load? Is there any way to completely stop the browser from sending OPTIONS requests?

Answer

Leo Correa picture Leo Correa · Apr 29, 2015

edit 2018-09-13: added some precisions about this pre-flight request and how to avoid it at the end of this reponse.

OPTIONS requests are what we call pre-flight requests in Cross-origin resource sharing (CORS).

They are necessary when you're making requests across different origins in specific situations.

This pre-flight request is made by some browsers as a safety measure to ensure that the request being done is trusted by the server. Meaning the server understands that the method, origin and headers being sent on the request are safe to act upon.

Your server should not ignore but handle these requests whenever you're attempting to do cross origin requests.

A good resource can be found here http://enable-cors.org/

A way to handle these to get comfortable is to ensure that for any path with OPTIONS method the server sends a response with this header

Access-Control-Allow-Origin: *

This will tell the browser that the server is willing to answer requests from any origin.

For more information on how to add CORS support to your server see the following flowchart

http://www.html5rocks.com/static/images/cors_server_flowchart.png

CORS Flowchart


edit 2018-09-13

CORS OPTIONS request is triggered only in somes cases, as explained in MDN docs:

Some requests don’t trigger a CORS preflight. Those are called “simple requests” in this article, though the Fetch spec (which defines CORS) doesn’t use that term. A request that doesn’t trigger a CORS preflight—a so-called “simple request”—is one that meets all the following conditions:

The only allowed methods are:

  • GET
  • HEAD
  • POST

Apart from the headers set automatically by the user agent (for example, Connection, User-Agent, or any of the other headers with names defined in the Fetch spec as a “forbidden header name”), the only headers which are allowed to be manually set are those which the Fetch spec defines as being a “CORS-safelisted request-header”, which are:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type (but note the additional requirements below)
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width

The only allowed values for the Content-Type header are:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

No event listeners are registered on any XMLHttpRequestUpload object used in the request; these are accessed using the XMLHttpRequest.upload property.

No ReadableStream object is used in the request.