Javascript 也就是说,XDomainRequest并不总是有效的

Javascript 也就是说,XDomainRequest并不总是有效的,javascript,internet-explorer,cross-domain,xdomainrequest,Javascript,Internet Explorer,Cross Domain,Xdomainrequest,我正在尝试在IE上进行跨域操作 我使用XDomainRequest,并为所有事件(OneError、onload、onprogress和ontimeout)植入日志来监控进度 它有时能工作,但并不总是(一台计算机,IE9,同一个站点,同一个请求,三台或四台计算机中有一台工作;另一台计算机,IE8,可能两台计算机中有一台工作)。我没有从日志中得到任何有用的信息,因为没有触发任何事件 我很困惑。有IE的调试工具吗?为什么有些时候XDomainRequest不起作用 非常感谢 科罗宁有着完全相同的问题

我正在尝试在IE上进行跨域操作

我使用XDomainRequest,并为所有事件(OneError、onload、onprogress和ontimeout)植入日志来监控进度

它有时能工作,但并不总是(一台计算机,IE9,同一个站点,同一个请求,三台或四台计算机中有一台工作;另一台计算机,IE8,可能两台计算机中有一台工作)。我没有从日志中得到任何有用的信息,因为没有触发任何事件

我很困惑。有IE的调试工具吗?为什么有些时候XDomainRequest不起作用

非常感谢
科罗宁有着完全相同的问题。简短解决方案:

  • 使用此代码:
  • 更新:链接已断开,请在此处查找jaubourgs修复程序:

  • 添加
    xdr.onprogress=function(){}在该xdr.js文件中
  • 可以在这里的jQuery主题讨论中找到详细信息

    在最后的回复中,包含了xdr.onprogress修复程序,该修复程序源于此bug讨论,标题恰当

    “如果未指定所有事件处理程序,IE9 RTM-XDomainRequest发出的请求可能会中止”

    XDomainRequest对象中至少有两个重要错误,一个影响IE8,另一个影响IE9

    问题1-垃圾收集

    在Internet Explorer 8中,XDomainRequest对象在调用send()但尚未完成后被错误地接受垃圾收集。此错误的症状是开发工具的网络跟踪显示请求“已中止”,并且没有调用任何错误、超时或成功事件处理程序

    典型的AJAX代码如下所示:

    function sendCrossDomainAjax(url, successCallback, errorCallback) {
      var xdr = new XDomainRequest();
      xdr.open("get", url);
      xdr.onload = function() { successCallback(); }
      xdr.onerror = function() { errorCallback(); }
      xdr.send();
    }
    
    在本例中,包含XDomainRequest的变量超出范围。如果用户运气不好,IE的Javascript垃圾收集器将在send()异步完成之前运行,请求将被中止。即使XDomainRequest对象可以被捕获到OnLoad和OnError事件处理程序中,IE也会看到整个对象图没有对它的引用,并且会对它进行垃圾收集。IE应该“固定”对象直到完成

    您会注意到internet上还有很多其他讨论提到在xdr.send()周围放置setTimeout;调用将以某种方式“解决”神秘的XDomainRequest失败。这是一种混乱,完全不正确。所发生的一切就是XDomainRequest对象被“固定”到setTimeout闭包中,而不是像现在这样快速地接受垃圾收集。这并不能解决问题

    要正确解决此问题,请确保XDomainRequest存储在全局变量中,直到请求完成。例如:

    var pendingXDR = [];
    
    function removeXDR(xdr) {
      // indexOf isn't always supported, you can also use jQuery.inArray()
      var index = pendingXDR.indexOf(xdr);
      if (index >= 0) {
        pendingXDR.splice(index, 1);
      }
    }
    
    function sendCrossDomainAjax(url, successCallback, errorCallback) {
      var xdr = new XDomainRequest();
      xdr.open("get", url);
    
      xdr.onload = function() {
        removeXDR(xdr);
        successCallback();
      }
    
      xdr.onerror = function() {
        removeXDR(xdr);
        errorCallback();
      }
    
      xdr.send();
      pendingXDR.push(xdr);
    }
    
    问题2-缺少OnProgress事件处理程序

    第二个问题已经为人所知。Internet Explorer 9在XDomainRequest对象中引入了回归,其中缺少(null)OnProgress事件处理程序将导致请求在尝试报告进度信息时中止

    对于快速请求,IE9从不尝试调用OnProgress事件处理程序,请求成功。某些情况下,例如IE由于太多打开的连接、网络延迟、服务器响应缓慢或请求或响应有效负载过大而延迟请求时,将导致IE9开始报告进度信息

    IE9尝试调用事件处理程序而不首先检查它是否存在,XDomainRequest对象会在内部崩溃并销毁自身

    要解决此问题,请始终确保将事件处理程序附加到OnProgress。考虑到这个bug,防御性地将事件处理程序添加到对象的所有事件中并不是一个坏主意

    var xdr = new XDomainRequest();
    xdr.open("get", url);
    xdr.onprogress = function() { };
    // regsister other event handlers
    
    其他问题

    我似乎有报告说,如果在调用.open()之前注册事件处理程序,XDomainRequest可能会失败。同样,出于防御,在.open()和.send()调用之间注册它们也不是一个坏主意。我还没有亲自验证它是否是一个真正的bug

    如果遇到“拒绝访问”错误,那是因为XDomainRequest不允许目标页和主机页之间存在不匹配的URI方案。换句话说,尝试不要从HTTPS页面调用HTTP资源

    当心互联网上的大多数XDomainRequest库。我查看了大多数流行的插件,例如各种jQueryAjax传输插件(包括在这里的另一个答案中链接的插件)

    当然,XDomainRequest受其所有正常操作的约束。这些本身并不是bug,与alernactives(iframe kludges、Flash crossdomain.xml传输)相比,它们并不是那么差


    我在这里发布了一个新的基于公共域许可证的jQuery AJAX XDomainRequest传输:

    使用IE的内置JavaScript调试器进行调试(点击F12打开它),或者使用(这是免费的)。嗨,gilly3,我尝试了F12,但没有显示任何内容。我现在正在检查VisualWebDeveloper~~非常感谢。这个答案可能帮我省了好几天的工作。Internet Explorer将是我的死亡。这是一个奇怪地没有被注意到的伟大答案。你无法想象你如何帮助我。太棒了!当我试图修复这个bug时,我发疯了。这是farLate给聚会的最好答案,但是把
    var dummy=xdr
    放在onload/onerror中能解决xdr从GC到完成的问题吗?这将节省对全球合作的需要。