繁体   English   中英

Mozilla中XMLHttpRequest的responsetext为null(空白)

[英]responsetext of XMLHttpRequest is null(blank) in Mozilla

当我在IE中运行以下代码时,它运行良好。

但是在mozilla ff中,layerId的值为空,因为reqGetSubMenuRef22.responseText在第1行为null。

function ajaxFunctionCallGetSubMenuRef22(url)
{
    if (window.XMLHttpRequest) { // Non-IE browsers and IE>=7
      reqGetSubMenuRef22 = new XMLHttpRequest();

      reqGetSubMenuRef22.onreadystatechange = processStateChangeGetSubMenuRef22;
      try {
        reqGetSubMenuRef22.open("GET", url, true);
        (( reqGetSubMenuRef22.setRequestHeader && method == "GET" ) ?  reqGetSubMenuRef22.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") : reqGetSubMenuRef22 );
      } catch (e) {
        alert(e);
      }
      reqGetSubMenuRef22.send(null);
    } 
    else if (window.ActiveXObject) { // IE    
      reqGetSubMenuRef22 = new ActiveXObject("Microsoft.XMLHTTP");
      if (reqGetSubMenuRef22) {
        reqGetSubMenuRef22.onreadystatechange = processStateChangeGetSubMenuRef22;
        reqGetSubMenuRef22.open("GET", url, true);
        reqGetSubMenuRef22.send();
      }
    }
}

function processStateChangeGetSubMenuRef22() 
{

    if (reqGetSubMenuRef22.readyState == 4) { // Complete
      if (reqGetSubMenuRef22.status == 200) { // OK response
            var textToSplit = reqGetSubMenuRef22.responseText; //line1

        if(textToSplit != null && textToSplit != '') {
                subMenuRef = textToSplit;
                }
            else {
                subMenuRef='';
                }

        layerId=subMenuRef;

processStateChangeGetSubMenuRef22 (不是最佳功能名称BTW)是一个回调。 它是在reqGetSubMenuRef22的上下文中调用的,因此if (reqGetSubMenuRef22.readyState === 4)使用if (reqGetSubMenuRef22.readyState === 4) ,然后尝试使用if (this.readyState === 4 && this.status === 200)
该函数被引用为变量reqGetSubMenuRef22readystatechange事件的处理程序,因此该函数将成为reqGetSubMenuRef22的方法,在逻辑上(在这种情况下)将this引用。

只是用一个类比来澄清这一点:您并不是将您的客厅称为Some Blvd Nr的客厅。 123,无论哪个镇,无论哪个国家 ,您呢? 当人们过来告诉你这是我的客厅,这是我们的家,这是我的住所 ...

同样, reqGetSubMenuRef22似乎是代码中的全局变量,您需要解决这个问题。 了解更多关于JS的this对MDN,并在阿贾克斯的情况下调用它也将证明是有益的进入closures


function readyStateCallback()
{
    if (this.readyState === 4 && this.status === 200)
    {
        console.log(this.responseText);
        //JSON string?:
        var resp = JSON.parse(this.responseText);
        //just txt:
        var resp = this.responseText;
        //HTML?
        document.getElementById('showResponseHere').innerHTML = this.responseText;
        //many more things you can do here...
    }
}

为什么reqGetSubMenuRef22不再起作用:

function sendRequest(str)
{
    var reqGetSubMenuRef22;//<-- local scope, only accessible in function
    var i;//local, too but different
    //try catch stuff: reqGetSubMenuRef22 is now an ajax object
    for (i=0;i<str.length;i++)
    {
        console.log(i);//just an example, you'll see why
    }
    reqGetSubMenuRef22.onreadystatechange = readyStateCallback;//reqGetSubMenuRef22 is still local
    //setup reqGetSubMenuRef22, then:
    reqGetSubMenuRef22.send();
}//end function

当sendRequest函数返回时,所有局部变量都经过GC运算,变量i从内存中删除。 reqGetSubMenuRef22应该是,但是它附加了一个事件,该事件将触发在全局范围或另一个仍然存在的范围中声明的函数。
该对象保持活动状态,因为JS正在侦听reqGetSubMenuRef22对象上的onreadystatechange事件。 因此,即使它的名称不再与任何东西连接,该对象仍然非常“在那里”。 不是全局对象(aka窗口)调用readyStateCallback函数,而是ajax对象( reqGetSubMenuRef22 )调用。 因此,您可以使用this从该函数内部访问ajax对象,该对象始终指向调用该函数的对象。 (调用相同的函数,如readyStateCallback();这将指向全局对象( window ))回调完成其工作后, this或ajax对象将被垃圾回收,除非由于其他原因发生,或者程序中仍然引用了它。

我在解释这些内容时感到很糟糕,而且我也非常清楚,我在这里简化工作,在各处使用快捷键都非常过分。 但请不要阅读了关于this在JavaScript中。
顺便说一句:一个对象在函数返回后仍然保持活动状态,实际上是某种形式的关闭:变量超出范围,但仍然可以被引用。 归根结底,这允许使用一些非常强大的构造,所以我也敦促您也对此进行研究!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM