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

Posted

技术标签:

【中文标题】来自 IE 的不一致的 ajax (XDR) 响应【英文标题】:Inconsistent ajax (XDR) response from IE 【发布时间】:2011-07-12 03:18:33 【问题描述】:

我正在从通过 IE 插件注入到每个页面的 iframe 发出 ajax 请求。我正在使用 IE 的 cross domain request,因为 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();

【问题讨论】:

只是一个随机猜测:您可以尝试在 URL 的末尾添加一个无意义的参数,以确保浏览器绕过它的缓存......如果它发生在我身上,我会自己尝试,但是你可能没有兴趣在完全猜测上浪费时间:-) ...或者只使用POST,它根本不会被缓存。另外,我会绑定xdr.onerror = 以查看它是否会触发。不幸的是,没有 XDR 错误的错误描述。另外,确保 'Access-Control-Allow-Origin 标头设置为 * @Point,t 实际上是 math.random ...我已经编辑了我的答案。这是一个很好的猜测。虽然这不会被缓存 @jAndy,Access-Control-Origin 设置为 * 并且 xdr.onerror 不会触发任何内容 好的。你可以想象我在这样的事情上浪费了很多时间:-) 【参考方案1】:

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

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

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

【讨论】:

我们测试了网络故障。这并不是说。并且没有返回 404。所有资源都找到了。【参考方案2】: 首先,添加一个 onerror 处理程序来调试你的东西。记录它们,看看到底发生了什么。 其次,您的“math.random”方法存在缺陷。更好的选择是使用 new Date().getTime(),这将确保随着时间的推移您有一个独特的请求。 第三,您可以(可能应该)使用 POST 方法绕过 IE 明显基于标准的行为 (;-))

【讨论】:

【参考方案3】:

最后一分钟发现了问题。在我的情况下,我需要指定一个超时值,即使请求没有超时。为了正确调试 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');
            

【讨论】:

谢谢 - 我也错过了超时 - 它的默认值似乎是 0! 如果它对任何人有帮助,我刚刚与我的应用程序的 IE9 XDR 请求作斗争,我发现当您调用 open() 方法时,超时似乎被重置(通过手动构造和检查 XDomainRequest控制台中的对象)。在调用 open 方法后设置超时之前,我遇到了随机故障。 (我仍然事先设置好,以防万一)。【参考方案4】:

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

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

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

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

【讨论】:

【参考方案5】:

您在这里命名标题是正确的。体验比较不一致。让我们来看看它......

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 相当“松散”,因为它们不会在缺少句柄方法时中止。

【讨论】:

不敢相信,但设置所有回调确实为我解决了问题。这是否记录在某处?

以上是关于来自 IE 的不一致的 ajax (XDR) 响应的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Firefox 中解码来自 jQuery $.ajax 请求的 XML 响应

IE 11问题-自动缓存来自GET请求的响应-Reactjs

认识XDR-扩展威胁检测与响应平台

ajax的不可能响应

为什么IE9用try / catch区别对待XDR

跨域梳理