What status code should a well-written HTTP server return when it gets a CORS preflight (OPTIONS
) request?
200
, 204
or something else?
Should the status code be different in case origin is allowed (and corresponding headers will be set) or not allowed (and CORS headers will not be set or will not match the origin)?
The gist of it is, just use
200
.A little more generally: You should just send back the same status code for the CORS preflight
OPTIONS
request that you’d send back for any otherOPTIONS
request. The relevant specs don’t require or recommend anything more than that.As far the relevant specs: The Fetch spec at https://fetch.spec.whatwg.org/ is where requirements for the CORS protocol are defined, and it says the status can be anyhing in the range
200
-299
.That’s from the CORS-preflight fetch algorithm, which has a step saying it can be any “ok status":
And as far as what an “ok status” is, the spec says this:
Beyond that though, the Fetch spec doesn’t recommend any particular status within
200
-299
.The other relevant spec here is the HTTP 1.1 spec, which has a section defining semantics of all HTTP response status codes, and within that, a specific section that defines Successful 2xx codes.
And within that section there’s a specific section for 200 OK, which says this:
So a response to a CORS preflight OPTIONS just needs to be:
Access-Control-Allow-Methods
andAccess-Control-Allow-Headers
response headers)That’s what
200 OK
is defined by the HTTP spec to be, so you can stop right there.But if you read through the rest of the
2xx
codes in that section, you can confirm the semantics of none of them make sense for anOPTIONS
response—except for204 No Content
.Now as far as
204 No Content
goes, there’s nothing wrong with using it forOPTIONS
responses—but as far as I can see, there’s also not really any point. That’s because:OPTIONS
payloadOPTIONS
(and wouldn’t do anything with any payload that did come back)…so as far as I can see there’s no practical purpose in using a specific
204
status code in anOPTIONS
response to explicitly tell clients there’s no payload.It’s possible I could be wrong, though, and there’s some nuance I’m missing. But I don’t think so.
No, I don’t think it should be different. I don’t know what standard-defined code other than
200
or204
you could use anyway—but regardless of that, the specs don’t require it to be any different and don’t define any different use if it is. And think about it: What is any existing client code going to do any differently due to any difference in the status codes for those two cases?If the answer to that question is, “Nothing”, as far as I can see there’s no point in making it different.
Given all the above, the bottom line is: just send
200 OK
for CORS preflightOPTIONS
responses. Sending any code other than just200 OK
isn’t necessary or useful.