2012-07-18 108 views
0

當我在IE中運行下面的代碼時,它運行正常。XMLHttpRequest的responsetext在Mozilla中爲null(空白)

但是在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; 

回答

0

processStateChangeGetSubMenuRef22(不是最好的func名字BTW)是一個回調。它在reqGetSubMenuRef22的上下文中調用,因此寧可使用if (reqGetSubMenuRef22.readyState === 4),請嘗試使用if (this.readyState === 4 && this.status === 200)
該函數被引用爲變量的readystatechange事件的處理程序,因此函數將是邏輯上(在這種情況下)this引用的方法reqGetSubMenuRef22

只是用一個比喻來澄清這一點:你不把你的起居室稱爲Some Blvd Nr。的起居室。 123,無論小鎮,無論國家,你呢?當人們過來你說這是我的客廳裏,這是我們的家,這是我住的地方 ...

而且reqGetSubMenuRef22似乎是在代碼中的全局變量,你需要解決。在MDN上閱讀關於JS的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事件。所以即使它的名字已經不再與任何東西相連,這個對象仍然是「非常」的。不是全局對象(aka窗口)調用readyStateCallback函數,但ajax對象(reqGetSubMenuRef22)。因此,您可以使用this從該函數內部訪問ajax對象,該對象始終指向調用該函數的對象。 (調用與readyStateCallback();相同的函數,這將指向全局對象(window))回調完成後,它的作業this或ajax對象將被垃圾收集,除非發生其他事件,或者它仍然在您的程序中的其他地方被引用。

我在解釋這件事上很糟糕,而且我都意識到我在這裏簡化了一些東西,並在各地都採取了捷徑。但請在JavaScript中閱讀this
順便說一句:一個對象在一個函數返回後仍然保持活動狀態,實際上是一個閉包:一個變量超出了範圍,但仍然可以被引用。這就是它歸結爲什麼,這允許一些非常強大的構造,所以我希望你也看看這個!

+0

謝謝你的答覆。 我用這個替換了reqGetSubMenuRef22。但它仍然不起作用。以下是修改後的代碼。 (這個。readyState的== 4){//完成 \t如果(this.status == 200){// OK響應 \t \t \t \t變種textToSplit = reqGetSubMenuRef22.responseText; – 2012-07-18 10:13:59

+0

您必須替換所有出現的'reqGetSubMenuRef22'變量名稱。同樣使用'this.responseText','this'是對'reqGetSubMenuRef22'對象的引用,不能用它的名字來引用,因爲(我希望)它是一個函數變量,並且你不再處於該函數中。另外,如果你只是檢查'this.readyState === 4 && this.status === 200',那麼不要嵌套你的'if'語句,如果同樣好, ,海事組織,更清潔。我將使用模板'onreadystatechange'函數更新我的答案 – 2012-07-18 10:32:16

+0

@RakeshK:嘗試忽略'((reqGetSubMenuRef22.setRequestHeader && method ==「GET」)?reqGetSubMenuRef22.setRequestHeader(「Content-Type」,「application/x- www-form-urlencoded「):reqGetSubMenuRef22);'這一行也是。請不要使用全局變量,因爲您似乎在做這些事情。這是不好的做法,想象在第一個請求仍在處理的時候發送請求,當使用全局變量(對這兩個請求使用相同的變量)時,它會導致錯誤。如果某些東西只能在IE中運行,那麼你應該把它當作一個不好的標誌。特別是因爲它不再是最大的瀏覽器,chrome也是 – 2012-07-18 14:05:53

相關問題