为什么没有 POST 请求的 CORS 预检检查?

Why isn't there a CORS preflight check for POST requests?

假设有一个名为 email.com 的假想电子邮件网站和一个名为 evil.com 的邪恶网站。 email.com 使用 POST 个请求发送电子邮件。

在其计算机上保存了 email.com 会话 cookie 的用户访问 evil.com,并且 evil.comemail.com 发送了一个 http POST 请求发送诈骗电子邮件。据我了解,服务器会在不进行任何检查的情况下从用户帐户发送电子邮件,因为浏览器随请求提供了会话 cookie,并且预检检查不适用于 POST,即使 CORS 不适用不要与 evil.com 分享来自 email.com 的回复,因为它 Access-Control-Allow-Origin 不包含 evil.com 没关系,因为电子邮件已经发送了。

我知道这可以通过使用例如 CSRF 令牌来防止,但为什么不对 POST 请求实施预检呢?

您声称

preflight checks don't apply to POST

但这是不正确的:碰巧使用 POST 方法的 so-called simple requests 没有预检,但是 non-simple POST 请求确实得到预检。

例如,以下脚本 运行 在除 https://google.com 以外的任何 Web 来源的上下文中都会触发 CORS 预检,因为根据 the Fetch standard (which contains the de facto CORS specification), X-Foo is not a CORS-safelisted request header:

let opts = {
  method: "POST",
  headers: {
    "X-Foo": "foo"
  }
};
fetch("https://google.com", opts);

或者,查看 this particular instance of Jake Archibald's CORS playground

此外,CORS 预检从未打算作为针对 CSRF 的防御机制;这种信念是一种普遍的误解。相反,预检的目的是保护浏览器支持 cross-origin 请求出现之前的服务器。有关 CORS 预检背后的基本原理的更多详细信息,请参阅此 more complete answer