6

我正在从通过 IE 插件注入到每个页面的 iframe 发出 ajax 请求。我正在使用 IE 的跨域请求,因为 IE 的 jQuery ajax 失败。这在 IE8 和 9 上 75% 的时间都有效。另外 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();
4

5 回答 5

9

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

然后我尝试将调用xdr.send置于超时状态,如下所示:

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

它奏效了。我不知道为什么,但也许这对其他人有帮助。

于 2011-07-14T19:52:36.330 回答
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 相当“松散”,因为当句柄缺少方法时它们不会中止。

于 2012-06-19T15:57:54.897 回答
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');
            }
于 2011-03-23T20:21:15.807 回答
0

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

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

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

于 2011-03-18T13:35:14.883 回答
0
  • 首先,添加一个 onerror 处理程序来调试你的东西。记录它们,看看到底发生了什么。
  • 其次,您的“math.random”方法存在缺陷。更好的选择是使用 new Date().getTime(),这将确保随着时间的推移您有一个独特的请求。
  • 第三,您可以(可能应该)使用 POST 方法绕过 IE 明显基于标准的行为(;-))
于 2011-03-23T18:10:07.143 回答