我正在使用凭据和预检请求实施CORS,我有点迷惑为什么预检请求在Firefox 30中始终失败但在Safari(7.0.2)和Chrome 35中有效。我认为这个问题与" Why does the preflight OPTIONS request of an authenticated CORS request work in Chrome but not Firefox?"不同因为我没有收到401,而是来自浏览器客户端的特定于CORS的消息:
"阻止跨源请求:同源策略禁止在http://myurl.dev.com读取远程资源。这可以通过将资源移动到同一域或启用CORS来解决。"
没有显示源代码,这就是我正在做的事情:
在服务器上:
OPTIONS响应的标题:
POST响应的标题:
在浏览器客户端中:
jQuery.ajax({
url: requestUrl,
type: 'POST',
data: getData(),
xhrFields: {
withCredentials: true
}
});
根据规范,这将触发OPTIONS预检请求,该请求需要在其响应中包含CORS头。我已多次阅读W3C规范,但我无法确定我在该预检响应中做错了什么。
答案 0 :(得分:1)
问题:“为什么此 CORS 请求仅在 Firefox 中失败?”
答案: 虽然与 OP 的具体情况无关,但它可能有助于您了解 Firefox 默认不信任 Windows 证书存储中的 CA(证书颁发机构) ,这可能会导致 Firefox 中的 CORS 请求失败(正如 Svish 在问题评论中所暗示的那样)。
允许 Firefox 信任 Windows 证书存储中的 CA:
about:config
security.enterprise_roots.enabled
作为名称
将值设置为 true
答案 1 :(得分:0)
我注意到当您发送带有Cookie设置的CORS(跨源资源共享)请求时,Firefox不会发送所需的响应标头。
解决方案:
以下解决方案仅为OPTIONS请求添加标头,并仅接受来自example.com的请求。您可以更改其他请求方法和预期主机的实现。
JS CODE
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;
}