簡體   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