2012-03-29 26 views
11

Tôi đã đoạn mã sau đó là cho tôi một tin nhắn Method POST, Status (canceled) lỗi:Method POST, Tình trạng tin nhắn (hủy bỏ) lỗi

$(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."); 
    } 

}); 

Mã này thực sự hoạt động miễn là mỗi yêu cầu ajax hoàn tất, nhưng nếu tôi gõ nhanh vào txt1, tức là nhập ký tự tiếp theo trước khi yêu cầu trước kết thúc, tôi nhận được thông báo lỗi Method POST, Status (canceled).

Bất kỳ ai biết tại sao điều này đang xảy ra và cách sửa lỗi?

+0

Điều này có thể hữu ích, hãy xem [stackoverflow.com/questions/6678467] (http://stackoverflow.com/questions/6678467/ajax-sent-on-keyup-duplicates-results-when-fast-typing) – safarov

+0

Oleg có lẽ là câu trả lời hay nhất ở đây. Bản sửa lỗi của anh ấy sẽ giúp bạn tiến xa hơn với kịch bản. BAO GIỜ: trong khi đọc mã của bạn tôi thấy rằng bạn không tạo ra mã lý tưởng cho vấn đề này. Tôi sẽ tạo ra một câu trả lời cho bạn. –

Trả lời

11

Tôi cho rằng vấn đề rất dễ dàng. Nếu bạn gọi xhr.abort(); thì gọi lại error$.ajax sẽ được gọi là cho yêu cầu đang chờ xử lý. Vì vậy, bạn chỉ nên bỏ qua trường hợp như vậy bên trong số gọi lại là error. Vì vậy, trình xử lý error có thể được sửa đổi thành

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 
} 

P.S. Có lẽ một số khác của tôi old answer về vấn đề đóng cũng có thể thú vị cho bạn.

0

Đó là vì bạn đang gọi phương thức abort có thể kích hoạt trình xử lý lỗi với thông báo lỗi thích hợp.

Bạn có thể chờ yêu cầu ajax trước đó hoàn thành trước khi thực hiện cuộc gọi tiếp theo.

+0

Tôi nên hủy bỏ quy trình chưa hoàn thành như thế nào nếu một quy trình khác cần được bắt đầu tại địa điểm đó? – oshirowanen

-1

Ajax là một loại hình async, nó không recommonded rằng u để gửi yêu cầu trên tất cả các sự kiện KeyUp, hãy thử các ...

async: false 

trong bài phương pháp ... nó sẽ tạm dừng các bài viết tiếp theo cho đến khi yêu cầu hiện tại đã thực hiện lời gọi lại

+3

Việc sử dụng 'async: false' không thể thực hiện được vì nó sẽ dừng trình duyệt cho đến khi yêu cầu hoàn tất và trả lời. – ShankarSangoli

+0

Tôi đồng ý. Với giải pháp này, bạn phá hủy toàn bộ khả năng nội dung được thêm động trong khi bạn đang nhập. –

0

Bạn đang sử dụng sự kiện keyup, điều này có vẻ là vấn đề.

Nếu có bất kỳ điều gì, bạn cần đợi sau khi nhập một ký tự trước khi thực hiện hành động.

Một giải pháp tốt hơn có thể là thực hiện theo cùng một chiến lược như JQuery AutoComplete COmponent.

-1

Thực tế bạn cần một phương thức setTimeout để ngăn chặn các cuộc gọi ajax dự phòng bị sa thải.

clearTimeout(timer); 

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

Điều này sẽ loại bỏ vấn đề của bạn.

+0

Câu trả lời này không hữu ích như thế nào? – trickyzter

0

Để khắc phục cả vấn đề của bạn và tiết kiệm số lượng cuộc gọi Ajax tôi đã viết ví dụ sau. Ví dụ này cho phép bạn xử lý hai trường hợp sau đây:

Trường hợp 1:

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

Trường hợp 2:

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

Trong ví dụ sau có được không cần phải hủy bỏ hoặc bỏ qua các cuộc gọi Ajax, bạn không gửi spam các cuộc gọi Ajax và bạn đang sử dụng một đối tượng để xử lý công việc của mình.(Tôi thậm chí jsFiddled nó dành cho bạn)

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); 

}); 

Hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan