CORS 预检请求的正确状态代码是什么?

What are proper status codes for CORS preflight requests?

well-written HTTP 服务器 return 在收到 CORS 预检 (OPTIONS) 请求时应该使用什么状态码?

200204 还是其他?

如果允许来源(并且将设置相应的 headers)或不允许(并且不会设置 CORS headers 或与来源不匹配),状态代码是否应该不同?

其要点是,只需使用 200

更一般一点:您应该只发回与 CORS 预检 OPTIONS 请求相同的状态代码,您会为任何其他 OPTIONS 请求发回。相关规范仅要求或推荐任何内容。

规范说明:https://fetch.spec.whatwg.org/ 的 Fetch 规范定义了 CORS 协议的要求,它表示状态可以是 200-[=15= 范围内的任何值].

来自 CORS-preflight fetch algorithm, in a step saying it can be any “ok status":

If a CORS check for request and response returns success and response’s status is
an ok status, run these substeps: …

关于什么是“正常状态”,规范是这样说的:

An ok status is any status in the range 200 to 299, inclusive.

除此之外,Fetch 规范不推荐 200-299 内的任何特定状态。

这里的另一个相关规范是 HTTP 1.1 规范,其中有一个部分定义了所有 HTTP 响应状态代码的语义,其中 a section that defines Successful 2xx 代码。

在该部分中有 a specific section for 200 OK,它表示:

The 200 (OK) status code indicates that the request has succeeded.
The payload sent in a 200 response depends on the request method.
For the methods defined by this specification, the intended meaning
of the payload can be summarized as:
…
OPTIONS  a representation of the communications options;

因此,对 CORS 预检选项的响应只需:

这就是 HTTP 规范定义的 200 OK,因此您可以就此打住。

但是如果你通读 the rest of the 2xx codes in that section, you can confirm the semantics of none of them make sense for an OPTIONS response—except for 204 No Content

现在就 204 No Content 而言,将其用于 OPTIONS 响应并没有 错误 ——但实际上也没有任何意义。那是因为:

  • 与其他一些方法不同,HTTP 规范定义了 OPTIONS 有效载荷没有用处
  • 因此在实践中,客户端不希望任何有效负载(内容)返回 OPTIONS(并且不会对返回的任何有效负载执行任何操作)

…所以在 OPTIONS 响应中使用特定的 204 状态代码来明确告诉客户端没有有效负载没有实际意义。

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)?

没有。除了 200204 之外,没有任何 standard-defined 代码可以使用——但无论如何,规范不要求它有任何不同,也没有定义任何不同的用途如果是。想一想:由于这两种情况的状态代码有任何差异,任何现有客户端代码会做哪些不同的事情?

如果答案是“没什么”,那么改变它就没有意义了。


鉴于以上所有内容,底线是:只需发送 200 OK 用于 CORS 预检 OPTIONS 响应。发送除 200 OK 之外的任何代码都没有必要也没有用。

我用了204。现在它不再跨浏览器工作了。使用 200。如果在预检中收到 204,Firefox 将开始拒绝 CORS 请求。它浪费了我将近 2 个小时的调试时间。

要学习的教训:当对网络标准有疑问时,不要选择有意义的规范(即 204 没有内容)...选择大多数人所做的(easy/stupid选择)