来自 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 响应