我不知道为什么这个 CORS 请求无法返回数据。
我在后端使用 Catalyst MVC,Firefox 24.0 作为浏览器。 jQuery 1.9.1.请注意以下事项:
- otherdomain.com 需要客户端证书。
- 直接命中资源会返回预期数据。(https://otherdomain.com/resource/1) 返回正确的数据。
我有一个简单的页面来测试请求:
<script type='text/javascript'>
function get_data() {
console.log("running");
$.ajax({
url: "https://otherdomain.com/resource/1",
dataType: 'json',
type: 'GET',
xhrFields: {
'withCredentials': true
},
crossDomain: true
}).success(function(data) {
console.log(data)
$('#output').html(data);
}).error(function(xhr, status, error) {
alert("error");
console.log(xhr);
});
}
$(document).ready(function() {
get_data();
});
</script>
</script>
这是我的请求标头:
GET /resource/1 HTTP/1.1
Host: otherdomain.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: https://mydomain.com/test.html
Origin: https://mydomain.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
这是我的响应标头。(查看源代码的副本来自Firebug Console)我在 catalyst 调试输出中看到请求为 200 OK 并发送内容。
HTTP/1.1 200 OK
Date: Mon, 28 Oct 2013 19:31:08 GMT
Server: HTTP::Server::PSGI
Vary: Content-Type
Content-Length: 653
Content-Type: application/json
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 1800
X-Catalyst: 5.90030
Via: 1.1 otherdomain.com
错误是从 ajax 调用中抛出的:
readyState: 0
responseText: ""
status: 0
statusText: "error"
Firebug 在请求事件中将响应正文显示为空,尽管它是 200 OK。
我认为在使用"withCredentials"时需要预报请求,但我没有看到通过火虫发送的选项。
此外,我的请求看不到添加Access-Control-Request-Header
,因此我没有从服务器返回任何Access-Control-Allow-Headers
。
现在,Catalyst 的前端是 Apache2,我在虚拟主机中使用 proxypass 将请求发送到 localhost:8080 上的 catalyst。我不确定这是否有任何影响,但认为这可能很重要。不过,它应该对浏览器是透明的。
感谢您的任何帮助!
- GET 请求不会进行预检。看这里
- 响应凭据请求时,服务器必须指定域,并且不能使用通配符。(不得为访问控制允许来源:*)。看这里
我有一个类似的问题,在 Chrome 中一切正常,但我在 Firefox 中的所有跨域请求都得到 405(以及 IE 的类似问题)。 我尝试添加xhrFields和crossdomain标志。 我也在使用之前发送实际做一个xhr.withCredentials = true
。 我确保我在服务后端有主机名匹配。 我使用访问控制允许凭据标头。
可能不同的一件事...我只在存在 Origin 标头时发送这些标头,因为如果我没有得到 Origin,我对 Access-Control-Allow-Origin 的唯一响应可能是*
,因为我不知道源是什么。