为什么这个跨域请求在其他浏览器中有效但在IE9中无效?

TMC*_*TMC 6 ajax cross-domain internet-explorer-9

我有一些Ajax代码可以在Safari,Chrome和Firefox中使用,但不能在IE9中使用.

页面已打开http://foo.com/test.aspx,它正在向托管的Web服务发出AJAX请求https://service.foo.com.我以为我不会有任何跨域问题,但鉴于IE9阻止它,它似乎我做:(

var tempUrl = "https://service.foo.com/dummy.svc/test?hi=bye";
$.get(tempUrl, "html");
Run Code Online (Sandbox Code Playgroud)

正如我所提到的,代码可以在其他3个浏览器中运行,而不是IE9.(我只关心IE9,而不是IE8或更老版本).

我做了一些挖掘,发现MSDN上的这篇文章说:

跨域请求需要网页和服务器之间的相互同意.您可以通过在窗口对象外创建XDomainRequest对象并打开与特定域的连接,在Web页面中启动跨域请求.浏览器将通过发送带有原始值的Origin头来从域的服务器请求数据.如果服务器使用*的Access-Control-Allow-Origin标头或请求页面的确切URL进行响应,它将仅完成连接.此行为是万维网联盟(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或在webservice上的https://service.foo.com?)

Orh*_*ral 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();
}
Run Code Online (Sandbox Code Playgroud)

注意:这适用于GET请求.

要在POST请求上进行调整,请更改以下行:

function newpostReq(url,callBack,data)
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

总而言之,打开连接作为POST请求(第1行),设置发布数据的urlencoded类型的请求标头(用特殊浏览器的try-catch包装)(第2行),然后发送数据(第3行).


Sea*_*sey 0

如果这在其他浏览器(支持 CORS)中有效,那么您的 SVC 似乎已经支持这一点,但可以肯定的是,请使用 Fiddler2 来查看发生了什么。

Access-Control-Allow-Origin头用于所请求的资源,而不是请求它的页面。