Đã hủy bỏ xử lý lỗi jquery Ajax để bỏ qua


81

Tôi muốn có một phương pháp xử lý lỗi chung cho các cuộc gọi ajax, đây là những gì tôi có bây giờ:

$.ajaxSetup({
  error: function (XMLHttpRequest, textStatus, errorThrown) {
    displayError();
  }
});

Tôi cần phải bỏ qua lỗi của aborted. errorThrownlà null và textStatuserror. Làm cách nào để kiểm tra aborted?


4
Đối với tôi textStatus là "hủy bỏ". Tôi thấy đây là một câu hỏi cũ - có lẽ nó đã thay đổi.
jackocnr

Với tôi, đó vẫn là "lỗi".
Jānis Elmeris

Có một điều đáng buồn là nó thay đổi tùy thuộc vào trình duyệt.
Christophe Roussy


1
Nếu bạn đang gọi điện thoại abortbằng tay (và tôi không chắc chắn khi nào nó sẽ được gọi), bạn có thể vượt qua trong các thông báo lỗi: abort("abort").
MyiEye

Câu trả lời:


52

Tôi đã phải đối phó với cùng một trường hợp sử dụng ngày hôm nay. Ứng dụng tôi đang làm việc có các cuộc gọi ajax kéo dài này có thể bị gián đoạn bởi 1) người dùng điều hướng đi hoặc 2) một số loại kết nối tạm thời / lỗi máy chủ. Tôi muốn trình xử lý lỗi chỉ chạy khi kết nối / lỗi máy chủ chứ không phải cho người dùng điều hướng đi.

Lần đầu tiên tôi thử câu trả lời của Alastair Pitts, nhưng nó không hoạt động vì cả hai yêu cầu bị hủy bỏ và lỗi kết nối đều đặt mã trạng thái và readyState thành 0. Tiếp theo, tôi thử câu trả lời của sieppl; cũng không hoạt động vì trong cả hai trường hợp, không có phản hồi nào được đưa ra, do đó không có tiêu đề.

Giải pháp duy nhất phù hợp với tôi là thiết lập trình lắng nghe cho window.onbeforeunload, thiết lập một biến toàn cục để cho biết rằng trang đã được tải xuống. Sau đó, trình xử lý lỗi có thể kiểm tra và chỉ gọi trình xử lý lỗi nếu trang chưa được tải xuống.

var globalVars = {unloaded:false};
$(window).bind('beforeunload', function(){
    globalVars.unloaded = true;
});
...
$.ajax({
    error: function(jqXHR,status,error){
        if (globalVars.unloaded)
            return;
    }
});

4
Đây không phải làm việc nếu một yêu cầu ajax bị gián đoạn bởi JavaScript
Sano J

1
Đây không phải là một câu trả lời hợp lệ. Trước khi dỡ tải có thể bị hủy bỏ. Nếu điều đó xảy ra, tất cả các lỗi Ajax tiếp theo sẽ bị bỏ qua.
LOST

@LOST Trình beforeunloadxử lý do người dùng định nghĩa. Tại sao bạn đặt globalVars.unloaded thành truenếu bạn định hủy dỡ tải theo cùng một phương pháp?
bluecollarcoder

@bluecollarcoder Tất cả những gì tôi đang nói là nếu bạn có một dự án lớn, nơi bạn phải đối mặt với vấn đề này, bạn phải đi và sửa tất cả trước khi tải các hanlders vào đó, chỉ thêm một dự án mới mà bạn đã cung cấp là chưa đủ.
LOST

beforeunloadkhông được gọi khi người dùng điều hướng đến trang khác hoặc được gọi quá muộn?
Christophe Roussy

43

Trong jQuery hiện đại, bạn chỉ có thể kiểm tra xem request.statusTextcó bằng 'abort':

error: function (request, textStatus, errorThrown) {
    if (request.statusText =='abort') {
        return;
    }
}

4
trong chrome, tôi có thể kiểm tra "hủy bỏ". trong firefox, tôi gặp "lỗi". Giải pháp từ @bluecollarcoder có vẻ là tốt nhất cho chúng tôi.
foxontherock

Có, điều này thay đổi tùy thuộc vào trình duyệt (các sự cố web thông thường ...)
Christophe Roussy

21

Một điều tôi nhận thấy là khi có một yêu cầu bị hủy bỏ, statusvà / hoặc readyStatebằng 0.

Trong trình xử lý lỗi chung của tôi, tôi có một dấu kiểm ở đầu phương pháp:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError) {
    //If either of these are true, then it's not a true error and we don't care
    if (jqXHR.status === 0 || jqXHR.readyState === 0) {
        return;
    }

    //Do Stuff Here
});

Tôi thấy điều này hoàn toàn phù hợp với tôi. Hy vọng điều này sẽ giúp bạn, hoặc bất kỳ ai khác gặp phải vấn đề này :)


3
Tôi nhận được cùng một trạng thái và readyState nếu ajax không thể kết nối với máy chủ để bắt đầu. Nhưng đây là lỗi tôi muốn xử lý. Chỉ bị hủy bỏ không.
Mitar

Có, điều này sẽ che dấu các lỗi khác mà bạn muốn thấy.
Christophe Roussy

10

Bạn sẽ muốn xem đối số textStatus được truyền vào hàm lỗi của bạn. Theo http://api.jquery.com/jQuery.ajax/ , nó có thể nhận các giá trị "thành công", "không sửa đổi", "lỗi", "hết thời gian chờ", "hủy bỏ" hoặc "phân tích cú pháp". "abort" rõ ràng là những gì bạn muốn kiểm tra chống lại.

Ghi chú dài hơn ở đây: jquery-gotcha-error-callback-triggered-on-xhr-abort


Tôi nghĩ rằng chúng tôi đã chơi đùa với điều này và nó đã không phát hiện ra loại thông báo lỗi hủy bỏ mà chúng tôi gặp phải.
sieppl

5

Vì câu trả lời bluecollarcoders không hoạt động đối với các yêu cầu ajax bị javascript bỏ qua, đây là giải pháp của tôi:

var unloaded = false;
...
$(window).bind('beforeunload', function(){
    unloaded = true;
});


$(document).ajaxError(function(event, request, settings) {
    if (unloaded || request.statusText == "abort") {
        return;
    }
    ...
}

ví dụ

handler = jQuery.get("foo")
handler.abort()

bây giờ sẽ bị bỏ qua bởi trình xử lý ajaxError


3

Dựa trên câu trả lời của Alastair Pitts ' , bạn cũng có thể làm điều này để có nhiều thông điệp hơn:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError)
{
    {
        if (jqXHR.status === 0)
        {
            alert('Not connect.\n Verify Network.');
        } else if (jqXHR.status == 404)
        {
            alert('Requested page not found. [404]');
        } else if (jqXHR.status == 500)
        {
            alert('Internal Server Error [500].');
        } else if (exception === 'parsererror')
        {
            alert('Requested JSON parse failed.');
        } else if (exception === 'timeout')
        {
            alert('Time out error.');
        } else if (exception === 'abort')
        {
            alert('Ajax request aborted.');
        } else
        {
            alert('Uncaught Error.\n' + jqXHR.responseText);
        }
    }
});

2
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {

    if (!jqXHR.getAllResponseHeaders()) {
        return;
    }           
}); 

1
Cũng không giúp được gì. Đối với cả yêu cầu bị hủy bỏ và lỗi kết nối với máy chủ, tiêu đề phản hồi đều trống.
Clovis Six

@ClovisSix Có, giải pháp trên kiểm tra xem tiêu đề phản hồi có trống hay không và thông báo lỗi gây khó chịu. Hoạt động tốt trên nhiều hệ thống thương mại mà chúng tôi chạy. Bạn có thể vui lòng cho biết thêm chi tiết những gì bạn cố gắng đạt được / vấn đề của bạn là gì?
sieppl

Chúng tôi đang hiển thị thông báo nếu bất kỳ yêu cầu nào của chúng tôi không thể kết nối với máy chủ. Chúng tôi không hiển thị chúng khi hủy bỏ thủ công nhưng vấn đề lớn nhất là khi người dùng điều hướng sang trang tiếp theo, trang này hiển thị lỗi kết nối và không có cách nào để phân biệt giữa yêu cầu bị hủy và lỗi kết nối. Tôi đã giải quyết vấn đề bằng cách đặt var trên window.onbeforeunload. Mà khá nhiều phát hiện một hủy bỏ thủ công.
Clovis Six,

Cũng ở đây với nhiều chi tiết hơn: ilikestuffblog.com/2009/11/30/…
Christophe Roussy

0

Tôi đã gặp vấn đề tương tự ở đây và những gì tôi đã làm như một giải pháp là đặt var "hủy bỏ" ngay trước lệnh gọi abort (), như bên dưới:

aborting = true;
myAjax.abort();

và chỉ hiển thị lỗi trên trình xử lý lỗi của yêu cầu ajax, nếu hủy bỏ không đúng.

$.ajax({
    [..]
    error: function() {
        if ( !aborting ) {
            // do some stuff..
        }
        aborting = false;
    }
});

0

Nếu bạn hủy bỏ yêu cầu ajax theo cách thủ công, bạn có thể làm như sau:

var xhr;
function queryData () {
    if (xhr) {
      // tag it's been aborted
      xhr.hasAborted = true;

      // manually canceled request
      xhr.abort();
    }

    xhr = $.ajax({
        url: '...',
        error: function () {
            if (!xhr.hasAborted) {
                console.log('Internal Server Error!');
            }
        },
        complete: function () {
           xhr = null;
        }
    });
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.