2011-03-09 28 views
6

我正在通过一个IE插件注入到每个页面上的iframe发出一个ajax请求。我使用IE的cross domain request,因为jQuery的ajax在IE中失败。这对IE8的75%时间工作& 9.其他25%,xdr.onload甚至没有火灾。来自IE的ajax(XDR)响应不一致

服务器php正在做它的工作......当onload确实不会触发时,日志看起来完全相同。而且,xdr.onerror也不会触发。

任何想法?

 thisURL = "http://example.com/getmsg.php?cmd=getMessage&iid=ddeb2c1228&uurl=http%3A%2F%2Fwww.cnn.com%2F&t=" + Math.random(); 

     // Use Microsoft XDR 
     var xdr = new XDomainRequest(); 
     xdr.open("GET", thisURL); 
     xdr.onload = function() { 
      // this is sometimes called, sometimes not in IE 
      alert('INCONSISTENT ALERT'); 
      callback(xdr.responseText); 
     }; 
     xdr.send(); 
+1

只是一个随机猜测:你可以尝试添加一个无用的参数到URL的末尾,以确保浏览器绕过它的缓存......如果它发生在我身上,我会自己尝试,但是你可能不会有兴趣浪费时间完成猜测:-) – Pointy 2011-03-09 18:17:15

+1

...或者只是使用'POST',它根本不会被缓存。另外,我会绑定'xdr.onerror ='来查看是否会触发。不幸的是,XDR错误没有错误描述。另外,请确保''Access-Control-Allow-Origin'标头设置为'*' – jAndy 2011-03-09 18:19:26

+0

@Point,t实际上是math.random ...我编辑了我的答案。这是一个很好的猜测。这不会被缓存,虽然 – Kyle 2011-03-09 18:35:56

回答

4

发现了问题,最后一分钟的基于标准的行为(;-))。在我的情况下,我需要指定一个超时值,即使请求没有超时。为了正确调试XDR问题,我建议使用下面的代码,每个警报都会告诉你代码的情况。正如我所说,在我的情况下,这是一个失踪的timeout声明。但是,下面的代码应该调试任何XDR问题:

 var xdr = new XDomainRequest(); 
      if (xdr) { 
       xdr.onerror = function() { 
//     alert('xdr onerror'); 
       }; 
       xdr.ontimeout = function() { 
//     alert('xdr ontimeout'); 
       }; 
       xdr.onprogress = function() { 
//     alert("XDR onprogress"); 
//     alert("Got: " + xdr.responseText); 
       }; 
       xdr.onload = function() { 
//     alert('onload' + xdr.responseText); 
        callback(xdr.responseText); 
       }; 
       xdr.timeout = 5000; 
       xdr.open("get", thisURL); 
       xdr.send(); 
      } else { 
//    alert('failed to create xdr'); 
      } 
+1

谢谢 - 我错过了超时 - 它似乎有一个默认值0! – 2012-08-29 02:36:25

+0

如果它帮助任何人,我只是与我的应用程序的IE9 XDR请求作斗争,并且我发现当您调用open()方法(通过手动构建并检查控制台中的XDomainRequest对象)时,超时会重置。在调用open方法之后,我设置了超时之前,我得到了随机故障。 (如果重要的话,我仍然会事先设置它)。 – Andrew 2013-01-22 19:56:09

0

这里很难给出明确的答案。

首先,您应该尝试使用Fiddler来查看您是否遇到某种网络故障。它将帮助您了解请求是否已实际完成以及服务器的响应。

其次,我不知道这是否适用,我们最近在IE上遇到了跨域问题。该代码在其他浏览器中运行良好 - Firefox,Safari和Chrome。这种情况下的问题证明,请求返回了预期的404。无论如何,IE停止了所有的执行,即使我们对404事件的错误处理从未被解雇。所以,你可能会在这里得到一些相同的结果。 Firefox,Safari等都让脚本继续。如果您返回错误,则可能希望使用错误值返回成功。

+0

我们测试了网络故障。这并不是说。并且没有返回404。所有资源都被找到。 – Kyle 2011-03-19 20:37:18

0
  • 首先,添加一个onerror处理程序来调试你的东西。记录他们,看看究竟发生了什么。
  • 其次,你的'数学随机'的方法是有缺陷的。更好的选择是使用新的Date()。getTime(),这将确保您在时间流逝时获得唯一的请求。
  • 三,你可以(也许应该)使用POST方法来绕过IE显然
9

我有一个非常类似的问题:XDomainRequests只有一些失败的时候,尽管提琴手显示正在发送的所有请求和响应头正是我打算。我已经定义了这些XDR对象上的每个事件处理程序和超时属性,并且没有任何处理程序正在被调用。 F12开发人员工具显示请求已中止。 GET和POST都可以中止到多个不同的域,但第一个请求总是成功的。

然后我试图把呼叫xdr.send在超时,如下所示:

setTimeout(function() { 
    xdr.send(); 
}, 0); 

和它的工作。我不知道为什么,但也许这会对别人有帮助。

7

在这里命名标题是正确的。经验相当不一致。让我们通过它...

var xdr, err, res, foo, url; 

xdr = new XDomainRequest(); 

err = function(){ alert("There was an error, operation aborted"); } 
res = function(){ alert("Success! " + xdr.responseText); } 
foo = function(){ return; } 

url = "http://hello.com/here/is/the/url/?query=true&whatever=asd"; 

xdr.onerror = err; 
xdr.ontimeout = foo; 
xdr.onprogress = foo; 
xdr.onload = res; 
xdr.timeout = 5000; 

xdr.open("get", url); 
xdr.send(null); 

XDomainRequest对象在每个IE中处理方式不同。

在IE9中 - > XDomainRequest对象要求所有句柄都有一个方法。这意味着,像onerror,onload,ontimeout和onprogress这些句柄都可以做。没有定义这些句柄的方法,那么你会得到一个“操作中止”的网络响应。

在IE7/8/9中 - 默认情况下XDomainRequest是ASYNC。无论xdr对象是否完成,它都会沿着堆栈进一步执行代码。 setTimeTimeout可能是一个解决方案,但不应该。

在这种情况下,触发一个事件并在执行任何进一步的代码之前监听事件。一个例子(在jQuery中)...

// call this method in xdr onload 
$(document).trigger("xdr_complete"); 

// use this wrapper in code you want to execute after the complete of xdr 
$(document).bind("xdr_complete", function(){ ... }); 

在IE7/IE8中,你会注意到它的工作原理。 IE7和IE8相当“松散”,因为它们在句柄缺少方法时不会中止。

+0

不能相信,但设置所有回调确实为我解决了问题。这是记录在某处吗? – 2014-04-30 11:18:44