XMLHttpRequest 的响应文本在 Mozilla 中为 null(空白)

responsetext of XMLHttpRequest is null(blank) in Mozilla

本文关键字:null 空白 中为 Mozilla 响应 文本 XMLHttpRequest      更新时间:2023-11-16

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

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

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(不是最好的func名称BTW(是一个回调。它是在reqGetSubMenuRef22的上下文中调用的,所以与其使用if (reqGetSubMenuRef22.readyState === 4),不如尝试使用if (this.readyState === 4 && this.status === 200)
该函数被引用为变量reqGetSubMenuRef22readystatechange事件的处理程序,因此该函数将是一个reqGetSubMenuRef22的方法,逻辑上(在这种情况下(用this引用。

只是为了用一个类比来澄清这一点:你不会把你的客厅称为某个大道123号的客厅,无论什么城镇,什么国家,你呢?当人们过来时,你说这是我的客厅,这是我们的家,这是我住的地方......

此外,reqGetSubMenuRef22似乎是代码中的全局变量,则需要解决这个问题。阅读更多关于JS在MDN上的this,并且在ajax调用的情况下,进入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'ed,变量i从内存中删除。 reqGetSubMenuRef22也应该是,但它附加了一个事件,此事件将触发在全局范围或另一个仍然存在的作用域中声明的函数。
该对象保持活动状态,因为 JS 正在侦听reqGetSubMenuRef22对象上的 onreadystatechange 事件。因此,即使它的名字不再与任何东西相连,这个对象仍然非常"在那里"。不是全局对象(又名窗口(调用readyStateCallback函数,而是 ajax 对象 (reqGetSubMenuRef22 ( 调用。因此,您可以使用 this 从该函数内部访问 ajax 对象,这将始终指向调用该函数的对象。(像readyStateCallback();这样调用相同的函数,这将指向全局对象(window((回调完成后,它的作业、this 或 ajax 对象将被垃圾回收,除非有其他事件发生,或者它仍然在程序中的其他地方被引用。

我不善于解释这些东西,而且我非常清楚我在这里过度简化事情,到处走捷径。但是请仔细阅读 JavaScript 中的this
顺便说一句:一个在函数返回后仍然保持活动状态的对象,实际上是某种闭包:变量超出了范围,但仍然可以引用。这就是它归结为的,这允许一些非常强大的结构,所以我敦促你也研究一下!