jQuery .ajax() 发送GET请求时会发送OPTIONS请求

4

我正在尝试从我的本地开发环境向服务器发送Ajax请求,使用的是:

<!DOCTYPE html>
<html>
<head>
    <title>JSSample</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
    $(function() {
        var params = {
            format: "JSON",
            season: "2015REG"
            // Request parameters
        };

        $.ajax({
            url: "https://<mysite>/sub/" + params.format + "/" + params.season,
            beforeSend: function(xhrObj){
                // Request headers
                xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","<mykey>");
            },
            type: "GET"
        })
        .done(function(data) {
            alert("success");
            console.log("Data: \n" + JSON.stringify(data));
        })
        .fail(function(error) {
            alert("error");
            console.log("Error" + JSON.stringify(error));
        });
    });
</script>
</body>
</html>

当我查看Firefox时,发现它实际上发送了一个OPTIONS请求 - 但是服务器没有做出响应(404未找到),因此我得到了一个跨域请求阻止错误。

OPTIONS 
XHR 
https://mysite [HTTP/1.1 404 Resource Not Found 2437ms]
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://mysite (Reason: CORS header 'Access-Control-Allow-Origin' missing).

我做错了什么?为什么jquery试图在我明确发送GET时询问选项?此外,我不拥有这个服务器,它属于另一家公司,该公司具有订阅API,因此我无法提供密钥或任何其他帮助来进行故障排除。


浏览器发送选项请求,页面的域名与您使用ajax到达的域名不同,基本上浏览器会向服务器询问:嘿,这个域名正在访问你,我要允许吗?正如您所说,您遇到了跨域错误。浏览器正在阻止您的请求。 - Ernesto
2个回答

1

当请求方法不是GET、HEAD或POST时,或使用自定义请求头时,则进行CORS预检(这就是正在发生的事情)

  • 您的情况下,您的自定义标头触发了预检

有效地,服务器拒绝了您的CORS请求。从您发布的内容来看,您需要在请求中使用自定义标头,因此远程服务器需要处理预检请求才能提供CORS资源

您尝试使用的服务器可能未设置为允许客户端(浏览器)连接,只允许“服务器”连接,这些连接没有跨域限制


你有什么想法为什么使用Chrome应用程序RestClient测试连接时它可以工作,但是当我只是制作这个简单的页面并在本地主机上加载它时却不能工作? - Derek
因为Chrome应用程序不是网页,所以不需要服务器发送CORS响应头。理论上,如果您想要的话,可以编写一个Chrome插件作为请求的代理。或者,使用您的服务器来代理客户端的请求。 - Jaromanda X
@Jaromanda X,非常感谢您提到自定义头部...我一直在追寻这个问题好几天了,而您的评论解决了我的困扰。 - GDP

1
如果另一个服务器是您自己的,则可以启用cors。否则,您不能(在大多数情况下*)通过ajax向外部域发出请求。
JavaScript和Web编程已经飞速发展了多年,但同源策略仍然存在。这防止JavaScript跨越域边界进行请求,并产生各种各样的黑客攻击来进行跨域请求。CORS引入了一种标准机制,可供所有浏览器用于实现跨域请求。该规范定义了一组标题,允许浏览器和服务器通信,以确定哪些请求被允许(或不允许)。CORS继续秉承开放网络的精神,为所有人带来API访问。

绕过CORS的一种方法是使用whateverorigin.org,以下是一个示例。

 $.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent('http://google.com') + '&callback=?', function(data){
    alert(data.contents);
});
    

抱歉,我刚刚更新了问题,说明我不拥有该服务器。然而,我能够使用Chrome RestClient应用程序测试请求,并且使用该客户端成功。这是否意味着我的代码存在问题? - Derek
JSONP 可能是另一种选择 - 但如果 OP 遇到这个问题,那么他正在做一些固有的错误。 - Kevin Friedheim
@ Derek,你可能想要更新你的问题,并提供完整的代码。 - Pedro Lobito

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接