为什么这个跨域请求在其他浏览器中可以工作但在IE9中不能工作?

6
我有一些Ajax代码在Safari,Chrome和Firefox中运作正常,但在IE9中却不能。该页面位于http://foo.com/test.aspx,正在向托管在https://service.foo.com上的webservice发出AJAX请求。我以为不会有任何跨域问题,但是由于IE9阻止它,似乎我确实有问题:(
var tempUrl = "https://service.foo.com/dummy.svc/test?hi=bye";
$.get(tempUrl, "html");

正如我所提到的,这段代码在其他三个浏览器中可以正常工作,但在IE9中无法正常工作。(我只关心IE9,不关心IE8或更早版本)。

我进行了一些调查,并在MSDN上找到了这篇文章,上面写着:

跨域请求需要Web页面和服务器之间的相互同意。您可以在Web页面中创建一个XDomainRequest对象并打开到特定域的连接来启动跨域请求。浏览器将通过发送具有来源值的Origin头从域的服务器请求数据。只有当服务器响应具有*或请求页面的确切URL的Access-Control-Allow-Origin头时,它才会完成连接。这种行为是世界范围内Web Consortium(W3C)Web应用程序工作组的草案框架的一部分,XDomainRequest对象与之集成。在使用XDR之前,我想验证比我聪明的人是否这样做是正确的方法。
  1. Response.AddHeader("Access-Control-Allow-Origin", "*");添加到我的页面
  2. 创建条件jscript代码,检测IE9并使用XDR而不是我正在使用的常规jquery调用$.get
我完全错了还是这是正确的方法?
(假设这是正确的方法,Acecss-Control-Allow-Origin响应头放在哪里——是放在我的页面http://foo.com/test.aspx上还是放在https://service.foo.com的Web服务上?)

一般而言,JQuery 感知浏览器的同源限制,并且不应在不支持 CORS 的浏览器中尝试使用它。您在 IE9 的 F12 开发人员工具控制台中看到脚本错误吗? - EricLaw
Eric,在开发工具控制台中没有抛出任何错误。 - TMC
3个回答

10

不要使用$.ajax(),而是使用这个自定义的代码:

function newpostReq(url,callBack)
{
    var xmlhttp;
    if (window.XDomainRequest)
    {
        xmlhttp=new XDomainRequest();
        xmlhttp.onload = function(){callBack(xmlhttp.responseText)};
    }
    else if (window.XMLHttpRequest)
        xmlhttp=new XMLHttpRequest();
    else
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
            callBack(xmlhttp.responseText);
    }
    xmlhttp.open("GET",url,true);
    xmlhttp.send();
}

注意:该方法仅适用于GET请求。

若要将其应用于POST请求,请更改以下行:

function newpostReq(url,callBack,data)

data是post请求的URL编码参数,例如:key1=value1&key2=value%20two

    xmlhttp.open("POST",url,true);
    try{xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");}catch(e){}
    xmlhttp.send(data);

总之,以POST请求方式打开连接(第1行),设置请求头以进行urlencoded类型的POST数据(对于异常浏览器,请将其包装在try-catch中)(第2行),然后发送数据(第3行)。


1
是的,使用GET请求它可以完美地工作,但是对于IE8和IE9中的POST请求我该怎么办? - Surya
如果我想要进行POST请求,我该怎么做?我正在我的服务中使用CORS,并需要在IE8和IE9中使用POST请求发送JSON数据。 - Surya

1

我刚刚也遇到了同样的问题。

PHP后端,正确的MIME类型,是的,

header('Access-Control-Allow-Origin: *');

在几乎所有浏览器中都能正常工作,除了IE9。

似乎jQuery.getJSON在ie9中不会自动执行XDR - 在同一域上创建服务代理后,它就可以正常工作了。

* 几乎 - Opera也有问题。

编辑:好吧,Opera确实和ie9有相同的问题。现在完美地解决了。

注意:Chrome、Safari和Firefox(3.6-5)使用ACAO:*进行跨域请求没有问题。

我不明白的是为什么a)微软使用不同的对象进行跨域请求,b)为什么jQuery不会透明地切换(或至少提供选择选项)。


0
如果其他支持CORS的浏览器中可以正常工作,那么您的SVC似乎已经支持了此功能,但为了确保,请使用Fiddler2查看其运行情况。 Access-Control-Allow-Origin 头是用于被请求资源而不是请求页面。

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