How do you send a custom header in a CORS preflight OPTIONS request?

I am trying to send a CORS request for a JSON payload. I control both the server and the client.

I'm following along here: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control

The server has a custom header that must be sent along with every request. This custom header therefore makes the request 'not simple' and thus the request must be preflighted with an OPTIONS request.

I can see jquery making the OPTIONS request, but it doesn't send the custom header along.

Methods I've tried:

  • using the beforeSend option: http://api.jquery.com/jQuery.ajax/
  • using an ajax prefilter: http://api.jquery.com/jQuery.ajaxPrefilter/

In both cases, the browser is not sending the custom header along.

I'm using FF 17.0.1, jquery 1.8.3.


Solution 1:

Your problem isn't with jquery, it's in how CORS works. Your beforeSend callback was probably working as expected... but browsers won't send custom headers in preflight requests, no matter what. This is by design; the purpose of the preflight request is to determine what information the useragent (browser) is permitted to send beyond the "simple" stuff defined in the CORS spec. Thus, for the useragent to send any non-simple data (such as your custom header) as part of the preflight request is self-defeating.

To instruct the useragent to include your custom header in the actual CORS request, include a Access-Control-Allow-Headers header in your preflight response. It's worth noting that if you're not overly concerned with what headers the useragent transmits, I believe you can just echo back the value of the Access-Control-Request-Headers request header field as the value of the Access-Control-Allow-Headers you send in the response.

You may also want to include some of the other Access-Control-Allow-* headers defined in the syntax section of the spec.

See also CORS - How do 'preflight' an httprequest?

See also Mozilla's CORS preflight example, which shows these headers in action.