2012-03-29 28 views
11

我有以下的代碼是給我一個Method POST, Status (canceled)錯誤消息:POST方法,狀態(已取消)錯誤信息

$(document).ready(function() { 
    var xhr = false; 

    get_default(); 

    $('#txt1').keyup(function() { 
     if(xhr && xhr.readyState != 4){ 
      alert("abort"); 
      xhr.abort(); 
     } 

     if ($("#txt1").val().length >= 2) { 
      get_data($("#txt1").val()); 
     } else { 
      get_default(); 
     } 
    }); 

    function get_data(phrase) { 
     xhr = $.ajax({ 
      type: 'POST', 
      url: 'http://intranet/webservices.asmx/GetData', 
      data: '{phrase: "' + phrase + '"}', 
      contentType: 'application/json; charset=utf-8', 
      dataType: 'json', 
      success: function(results) { 
       $("#div1").empty(); 

       if(results.d[0]) { 
        $.each(results.d, function(index, result) { 
         $("#div1").append(result.Col1 + ' ' + result.Col2 + '<br />'); 
        }); 
       } else { 
        alert("no data available message goes here"); 
       } 
      }, 
      error: function(xhr, status, error) { 
       var err = eval("(" + xhr.responseText + ")"); 
       alert(err.Message) ; 
      } 
     }); 
    } 

    function get_default() { 
     $('#div1').empty().append("default content goes here."); 
    } 

}); 

的代碼實際工作,只要每一個Ajax請求完成,但如果我輸入速度快到txt1,即在前一個請求完成之前鍵入下一個字符,我會收到錯誤消息Method POST, Status (canceled)

任何人都知道爲什麼會發生這種情況,以及如何糾正錯誤?

+0

這可能有用,看看[stackoverflow.com/questions/6678467](http://stackoverflow.com/questions/6678467/ajax-sent-on-keyup-duplicates-results-when-fast-typing) – safarov 2012-03-29 15:37:16

+0

奧列格在這裏可能是最好的答案。他的修復應該可以幫助你進一步瞭解腳本。但是:在閱讀你的代碼時,我發現你並沒有爲這個問題創建理想的代碼。我會爲你創建一個答案。 – 2012-04-05 12:17:42

回答

11

我想這個問題很簡單。如果調用xhr.abort();那麼error回調$.ajax將被稱爲爲掛起的請求。所以你應該忽略error回調中的這種情況。所以error處理程序可以被修改,以

error: function(jqXHR, textStatus, errorThrown) { 
    var err; 
    if (textStatus !== "abort" && errorThrown !== "abort") { 
     try { 
      err = $.parseJSON(jqXHR.responseText); 
      alert(err.Message); 
     } catch(e) { 
      alert("ERROR:\n" + jqXHR.responseText); 
     } 
    } 
    // aborted requests should be just ignored and no error message be displayed 
} 

附:可能是另一個關於密切問題的我old answer也可能對你有意思。

0

這是因爲您正在調用abort方法,可能會觸發錯誤處理程序並顯示相應的錯誤消息。

你可進行等待前面的Ajax請求使下一個電話之前完成。

+0

如果需要啓動另一個進程,我應該如何中止一個尚未完成的進程? – oshirowanen 2012-03-29 15:38:05

-1

Ajax是異步型,它不是recommonded是u到每個keyup事件發送請求時,嘗試...

async: false 
在POST方法

...這將暫停後續帖,直到當前請求完成其回調

+3

使用'async:false'不是可取的,因爲它會停止瀏覽器,直到請求完成並作出響應。 – ShankarSangoli 2012-03-29 15:41:09

+0

我同意。使用此解決方案,您可以在打字時摧毀動態添加內容的全部可能性。 – 2012-04-05 13:22:37

0

您正在使用keyup事件,這似乎是這個問題。

如果任何事情,你需要採取行動之前輸入一個字符後等待。

一個更好的解決方案可能是遵循同樣的戰略爲JQuery AutoComplete COmponent

-1

現實你爲了防止重複ajax調用被解僱需要的setTimeout方法。

clearTimeout(timer); 

if($("#txt1").val().length >= 2){ 
    timer = setTimeout(function(){ 
     get_data($("#txt1").val()); 
    }, 400); 
}else{ 
    get_default(); 
} 

這應該消除您的問題。

+0

這個答案沒用嗎? – trickyzter 2012-04-05 13:20:28

0

爲了解決您的問題並節省大量的Ajax調用,我寫了下面的示例。這個例子可以讓你處理以下兩種情況:

情況1:

The user types slow enough (lets say about one key every 200+ miliseconds 

情況2:

The user types fast (my average is about 20 to 50 miliseconds per key) 

在下面的例子中就沒有必要中止或忽略Ajax調用,您不是垃圾郵件發送Ajax調用,而是使用Object來處理您的工作。(我甚至jsFiddled爲你)

var Handler = { 

    /** 
    * Time in ms from the last event 
    */ 
    lastEvent: 0, 

    /** 
    * The last keystroke must be at least this amount of ms ago 
    * to allow our ajax call to run 
    */ 
    cooldownPeriod: 200, 

    /** 
    * This is our timer 
    */ 
    timer: null, 

    /** 
    * This should run when the keyup event is triggered 
    */ 
    up: function(event) 
    { 
     var d = new Date(), 
      now = d.getTime(); 

     if((now - Handler.lastEvent) < Handler.cooldownPeriod) { 
      // We do not want to run the Ajax call 
      // We (re)set our timer 
      Handler.setTimer(); 
     } else { 
      // We do not care about our timer and just do the Ajax call 
      Handler.resetTimer(); 
      Handler.ajaxCall(); 
     } 

     Handler.lastEvent = now; 
    }, 

    /** 
    * Function for setting our timer 
    */ 
    setTimer: function() 
    { 
     this.resetTimer(); 
     this.timer = setTimeout(function(){ Handler.ajaxCall() }, this.cooldownPeriod); 
    }, 

    /** 
    * Function for resetting our timer 
    */ 
    resetTimer: function() 
    { 
     clearTimeout(this.timer); 
    }, 

    /** 
    * The ajax call 
    */ 
    ajaxCall: function() 
    { 
     // do ajax call 
    } 

}; 

jQuery(function(){ 

    var field = jQuery('#field'); 

    field.on('keyup', Handler.up); 

}); 

希望這有助於。

相關問題