方法POST,状态(已取消)错误消息

我有以下代码,它给我一个Method POST, Status (canceled)错误消息:

 $(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 + '
' ); }); } 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)

任何人都知道为什么会这样,以及如何纠正错误?

我想问题很容易。 如果你调用xhr.abort(); 然后将为挂起的请求调用$.ajaxerror回调。 所以你应该在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 } 

PS可能另一个关于近距离问题的旧答案对你来说也很有趣。

这是因为您正在调用abort方法,该方法可能会触发error handling程序并显示相应的错误消息。

在进行下一次调用之前,您可以等待先前的ajax请求完成。

为了解决您的问题并节省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 ); }); 

希望这可以帮助。

您正在使用keyup事件,这似乎是问题所在。

如果有的话,你需要在输入一个字符之后等待,然后再采取行动。

更好的解决方案可能是遵循与JQuery AutoComplete COmponent相同的策略。

Ajax是一个异步类型,它不推荐你在每个keyup事件上发送请求,试试……

 async: false 

在post方法中…它将暂停后续post,直到当前请求完成其回调

实际上,您需要一个setTimeout方法,以防止激发冗余的ajax调用。

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

这应该根除你的问题。