32

我正在使用凭据和预检请求实现 CORS,我有点困惑为什么预检请求在 Firefox 30 中始终失败但在 Safari(7.0.2)和 Chrome 35 中有效。我认为这个问题不同于“为什么经过身份验证的 CORS 请求的预检 OPTIONS 请求在 Chrome 中有效,但在 Firefox 中无效? ” 因为我没有收到 401,而是来自浏览器客户端的特定于 CORS 的消息:

“跨域请求被阻止:同源策略不允许读取http://myurl.dev.com上的远程资源。这可以通过将资源移动到同一域或启用 CORS 来解决。”

在不显示源代码的情况下,这就是我正在做的事情:

在服务器上

选项响应的标题:

  • Access-Control-Allow-Origin:[[从此处的请求复制来源]]
  • 访问控制允许方法:“POST GET OPTIONS”
  • 访问控制允许标头:“X-Requested-With”
  • 访问控制允许凭据:“真”

POST 响应的标头:

  • Access-Control-Allow-Origin:[[从此处的请求复制来源]]
  • 访问控制允许凭据:“真”

在浏览器客户端中:

jQuery.ajax({
  url: requestUrl,
  type: 'POST',
  data: getData(),
  xhrFields: {
    withCredentials: true
  }
});

根据规范,这将触发一个 OPTIONS 预检请求,该请求需要在其响应中包含 CORS 标头。我已经多次阅读 W3C 规范,但我无法确定我做错了什么,如果有的话,在那个预检响应中。

4

4 回答 4

21

问题: “为什么这个 CORS 请求只在 Firefox 中失败?”


回答: 虽然与 OP 的具体情况无关,但它可能会帮助您知道 Firefox 默认不信任 Windows 证书存储中的 CA(证书颁发机构),这可能导致 Firefox 中的 CORS 请求失败(正如由Svish 在问题评论中)。


要允许 Firefox 信任 Windows 证书存储中的 CA:

  • 在 Firefox 中,about:config在地址栏中输入
  • 如果出现提示,请接受任何警告
  • 右键单击以创建一个新的布尔值,然后输入security.enterprise_roots.enabled作为 Name 将值设置为true
  • 然后重新测试失败的请求

答案来源: https: //support.umbrella.com/hc/en-us/articles/115000669728-Configuring-Firefox-to-use-the-Windows-Certificate-Store

于 2021-07-16T15:08:12.977 回答
16

请注意,Firefox 是这里唯一兼容的浏览器。如果按照https://fetch.spec.whatwg.org/#cors-preflight-fetch解析Access-Control-Allow-Methods失败,则需要返回网络错误。根据标头值的 ABNF,它绝对是一个逗号分隔的值。

于 2015-08-28T02:40:10.150 回答
0

我注意到,当您发送设置了 cookie 的 CORS(跨源资源共享)请求时,Firefox 不会发送所需的响应标头。

解决方案:

以下解决方案仅为 OPTIONS 请求添加标头,并仅接受来自 example.com 的请求。您可以更改其他请求方法和预期主机的实现。

JS代码

var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;

xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState == XMLHttpRequest.DONE) {
        if (xmlhttp.status == 200) {
            success_callback(xmlhttp.responseText);
        } else {
            error_callback(xmlhttp.statusText);
        }
    }
};
xmlhttp.open("DELETE", url);
xmlhttp.send(null);

当您发送 DELETE 请求时,浏览器会发送一个针对 OPTIONS 的飞行前请求,该请求需要响应标头中的Access-Control-Allow-Methods。根据此标头值发送实际的 DELETE 请求。在 Firefox 中,当您发送 DELETE 请求时,飞行前请求的响应标头没有预期的标头,因此它无法发送实际的 DELETE 请求。

为了克服这个问题,使用下面的 NGINX 服务器配置。

NGINX 代码

#handle CORS requests by adding required headers
if ($http_origin ~* .example.com) {
    set $cors "CORS-${request_method}";
}

if ($cors = "CORS-OPTIONS") {
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Headers' 'Content-Type';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
    add_header 'Access-Control-Allow-Origin' $http_origin;
}

很好地阅读 CORS:https ://www.html5rocks.com/en/tutorials/cors/

于 2017-03-30T14:06:21.220 回答
0

在 Firefox 中禁用 HTTPS-Only 模式为我解决了这个问题。我试图从 http://localhost 使用 HTTP 访问远程资源。

于 2022-02-04T14:17:39.403 回答