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

41,781

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.

Share:
41,781
mooreds
Author by

mooreds

My Blog: http://www.mooreds.com/weblog/ Another blog: https://letterstoanewdeveloper.com/ A book I wrote: https://leanpub.com/developingwithcordovacli/ My current job: Developer Advocate at FusionAuth: https://fusionauth.io/

Updated on July 14, 2022

Comments

  • mooreds
    mooreds almost 2 years

    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:

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

    I'm using FF 17.0.1, jquery 1.8.3.

  • mooreds
    mooreds over 11 years
    Thanks. I have things working after the preflight response happens, it's just the OPTIONS call that is the issue. Looks like I'll have to use a server based workaround.
  • broofa
    broofa over 11 years
    @mooreds - Can you provide a snapshot of the headers being sent/received in the preflight request? Is the issue that your server is rejecting the OPTIONS request because it doesn't have the custom header? 'Guess I don't understand why you need the server workaround still if things are working after the preflight response.
  • mooreds
    mooreds over 11 years
    yes, the OPTIONS request is being rejected because it doesn't have the custom header. On chrome, the rest of the data was still sent (that may have been because I am developing on localhost, not sure), but for Firefox, once the OPTIONS request failed, the rest of the request fails.
  • mooreds
    mooreds about 9 years
    The one workaround I've been able to come up with so far is to disable the custom header check for OPTIONS requests. Obviously that won't work if you don't have control of the server, so I'd love to hear any other suggestions. (This was an answer, but it was deleted)
  • Murray Rowan
    Murray Rowan about 8 years
    Did you ever find a solution to this that doesn't require (re-)configuring the server (i.e. if you have no access to it)?
  • mooreds
    mooreds about 7 years
    @MurraySmith nope, I had to make the change server side. Not sure if CORS has changed in the past few years, though.
  • David Edwards
    David Edwards almost 5 years
    Indeed, you not only need to ensure that your OPTIONS request contains the requisite access control headers, but you ALSO need to ensure that your server is configured to handle them properly, and return a response indicating to the browser that the options supplied are valid for this AJAX transaction. Someone at Facebook and YouTube forgot all of this today, and their sites crash and burn on my laptop with masses of CORS violation errors in the console (sigh) ..l.