2014-11-15 23 views
0

我試圖推翻ajax方法的發送方法。見下面我的代碼:XHR(Ajax)發送奇怪的原型行爲

(function() { 
    var beforeCall = window.XMLHttpRequest.prototype.open, 
     sendCall = window.XMLHttpRequest.prototype.send; 

    window.XMLHttpRequest.prototype.open = function() { 
     console.log("OPEN"); // Works 

     // Only called once, but Ajax has 5 states, which are should log 5 times 
     this.onreadystatechange = function(){ console.log("READYSTATE SOMETHING"); } 

     return beforeCall.apply(this, [].slice.call(arguments)); 
    }; 

    window.XMLHttpRequest.prototype.send = function() { 
     var origCallback = this.onreadystatechange; 
     this.onreadystatechange = function(){ 
      console.log("ONREADYSTATECHANGE"); // This log never gets called 
      if(origCallback) { 
       origCallback.apply(this, [].slice.call(arguments)) 
      } 
     }; 
     return sendCall.apply(this, [].slice.call(arguments)); 
    } 
})(); 

開放登錄,readyState的東西是隻記錄一次,但應該記錄每一個狀態?然後在我的發送函數中,我嘗試再次覆蓋它(應該在這裏,因爲也許我的網站已經有一個onreadystatechange並且我不想失去這個回調。所以,我需要它,但那個回調永遠不會被調用。

原始功能仍然與我的代碼工作上面,但我沒有得到我想要的額外日誌。

任何人都知道,爲什麼我用console.log("ONREADYSTATECHANGE")的onreadystatechange不會被調用?

我需要這個網站代碼是使用jQuery atm,但它也應該使用本地Javascript Ajax。

+0

更新了我的答案,在FireFox中犯了一個錯誤。您的代碼中的錯誤不能在FireFox 33.0中重新生成,除非在未打開頁面的全新選項卡的控制檯中運行它。我很好奇我的答案中的更新代碼會在其他瀏覽器中爲您產生什麼(我只有FireFox和Chrome)。 – HMR

回答

0

似乎beforeCall.apply(this, [].slice.call(arguments));導致Firefox中的錯誤:

window.XMLHttpRequest.prototype.open = function() { 
    console.log("OPEN"); // Works 

    // Only called once, but Ajax has 5 states, which are should log 5 times 
    this.onreadystatechange = function(){ console.log("READYSTATE SOMETHING"); } 
    console.log('still ok here'); 
    var ret = beforeCall.apply(this, [].slice.call(arguments));//error here 
    console.log('this is not happening'); 
    return ret;//neither does this 
}; 

它可以在Chrome 32.0.1700.107

也許這是因爲XMLHttpRequest是一個宿主對象和開放的功能並不像一個正常的JS函數應該表現,也許following answer仍然是相關的。

這可能只是一個FireFox錯誤,但這意味着不可能在任何XMLHttpRequest上收聽任何打開和發送的調用。您可以創建一個包裝器並使用該包裝器來調用XHR請求,但是隻能捕獲打開並從您的代碼發送;不能從第三方代碼

[更新]

看來,我犯了一個錯誤。

當我在google.com打開時,在firebug控制檯(FireFox 33)中運行以下代碼,但它在新的新選項卡中不起作用;必須訪問一個網站。

(function() { 
    var beforeCall = window.XMLHttpRequest.prototype.open, 
     sendCall = window.XMLHttpRequest.prototype.send; 

    window.XMLHttpRequest.prototype.open = function open() { 
     var ret; 
     console.log("OPEN"); 
     this.onreadystatechange = function(){ console.log("READYSTATE SOMETHING"); } 
     console.log('open still working'); 
     ret = beforeCall.apply(this, [].slice.call(arguments)); 
     console.log('open is done'); 
     return ret; 
    }; 

    window.XMLHttpRequest.prototype.send = function send() { 
     console.log('this is send'); 
     var origCallback = this.onreadystatechange,ret; 
     this.onreadystatechange = function(){ 
      console.log("ONREADYSTATECHANGE"); 
      if(origCallback) { 
       origCallback.apply(this, [].slice.call(arguments)) 
      } 
     }; 
     console.log('send still working'); 
     ret = sendCall.apply(this, [].slice.call(arguments)); 
     console.log('send done'); 
     return ret; 
    } 
})(); 

var xhr = new XMLHttpRequest(); 

xhr.open('GET','/'); 
//calling xhr.open with wrong order of parameters gives a not so elegant error 
//xhr.open('/','GET') 
xhr.send();