来自IE的不一致的ajax(XDR)响应

时间:2011-03-09 18:13:04

标签: javascript ajax internet-explorer cross-domain xdr

我正在通过IE插件向每个页面注入一个iframe发出ajax请求。我正在使用IE的cross domain request因为jQuery的ajax因IE而失败。这在IE8和IE上有75%的时间。 9.另外25%,xdr.onload甚至没有开火。

服务器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();

5 个答案:

答案 0 :(得分:9)

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

然后我尝试将对xdr.send的调用暂停,如下所示:

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

它有效。我不明白为什么,但也许这对其他人有帮助。

答案 1 :(得分: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对象是否完成,它都将在堆栈中进一步执行代码。设置setTimeout可能是一个解决方案,但不应该。

在这种情况下,触发事件并在执行任何进一步的代码之前侦听事件。这方面的一个例子是(在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相当“松散”,因为当缺少句柄方法时它们不会中止。

答案 2 :(得分: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');
            }

答案 3 :(得分:0)

很难在这里给你一个明确的答案。

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

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

答案 4 :(得分:0)

  • 首先,添加一个onerror处理程序来调试你的东西。记录它们,看看到底发生了什么。
  • 其次,你的'math.random'方法存在缺陷。更好的选择是使用新的Date()。getTime(),这将确保您随着时间的推移有一个唯一的请求。
  • 第三,你可以(可能应该)使用POST方法绕过IE显然基于标准的行为(;-))