2009-09-02 15 views
28

Nếu tôi điều hướng khỏi một trang ở giữa yêu cầu $ .ajax(), nó sẽ kích hoạt cuộc gọi lại lỗi. Tôi đã thử nghiệm trong Safari và FF với cả hai yêu cầu GET và POST.jQuery AJAX kích hoạt tính năng gọi lại lỗi khi dỡ cửa sổ - làm cách nào để lọc bỏ tải và chỉ bắt lỗi thực?

Một giải pháp tiềm năng là hủy bỏ tất cả yêu cầu AJAX khi tải trang, nhưng trình xử lý lỗi được gọi trước khi dỡ, vì vậy điều này dường như không thể.

Tôi muốn có thể xử lý các lỗi REAL như 500s một cách duyên dáng ở phía máy khách với cảnh báo lịch sự hoặc hộp thoại phương thức, nhưng tôi không muốn xử lý này khi người dùng điều hướng khỏi trang.

Làm cách nào để thực hiện việc này?

-

(Cũng lạ: Khi hướng đi từ một trang, xử lý lỗi nói rằng tham số textStatus là "lỗi", cùng nó ném khi nhận/yêu cầu xấu 500).

+2

cảnh báo lịch sự - Có điều gì không! – redsquare

+0

Bây giờ tôi đang đối mặt với tình huống tương tự với bạn, Graham. Cảm ơn vì đăng! –

+0

https://bugzilla.mozilla.org/show_bug.cgi?id=768596 – 4esn0k

Trả lời

24

Trong callback lỗi hoặc $.ajax bạn có ba đối số đầu vào:

function (XMLHttpRequest, textStatus, errorThrown) { 
    this; // options for this ajax request 
} 

Bạn có thể kiểm tra trực tiếp các xhr.status để có được mã phản hồi HTTP, ví dụ:

$.ajax({ 
    url: "test.html", 
    cache: false, 
    success: function(html){ 
    $("#results").append(html); 
    }, 
    error: function (xhr, textStatus) { 
    if (xhr.status == 500) { 
     alert('Server error: '+ textStatus); 
    } 
    } 
}); 

Edit: Để biết sự khác biệt giữa kết nối bị hỏng bởi trình duyệt và trường hợp máy chủ bị hỏng (bình luận của jasonmerino):

On dỡ bỏ các xhr.readyState phải là 0, nơi cho một tổ chức phi đáp ứng máy chủ xhr.readyState nên 4.

+4

Làm cho tinh thần, khi tải trạng thái = 0, cảm ơn. – Graham

+3

Trạng thái = 0 cũng nếu máy chủ không phản hồi (bị lỗi). – Mitar

+1

Vì giá trị này có cùng giá trị trạng thái, làm cách nào để phân biệt tải và không phản hồi? –

0

Lỗi gọi lại sẽ nhận được tham chiếu đến đối tượng XHR, kiểm tra mã trạng thái để xem đó có phải là lỗi máy chủ hay không?

4

(Tôi muốn thêm này như một bình luận cho câu trả lời chính nhưng chưa xây dựng đủ điểm để làm như vậy!)

Tôi cũng thấy điều này trong FF4 và Chrome (9.0.597.107). Có lẽ ở nơi khác nhưng đó là đủ xấu cho tôi muốn sửa chữa nó!

Một trong những điều đó là kỳ quặc về tình trạng này là trở XMLHttpRequest.status === 0

Mà có vẻ như một cách đáng tin cậy để phát hiện tình trạng này và, trong trường hợp đặc biệt của tôi, hủy bỏ việc xử lý lỗi tùy chỉnh mà hiển thị cho người dùng:

error: function (XMLHttpRequest, textStatus, errorThrown) { 
    if (XMLHttpRequest.status === 0) return; 
    // error handling here 
} 

cũng đáng nói đến là trên giả định nếu có thể là một vấn đề trong phân tích cú pháp JSON của bất cứ trình duyệt để đáp lại lòng $ .ajax() gọi, tôi cũng đã cố gắng trao đổi ra JSON.stringify gốc cho phiên bản Douglas Crockford (https://github.com/douglascrockford/JSON-js) nhưng điều đó không có sự khác biệt.

+3

Trạng thái = 0 cũng nếu máy chủ không phản hồi (bị lỗi). – Mitar

+0

Tôi vừa thử nghiệm và có - số 0 được trả về nếu máy chủ HTTP (Apache trong trường hợp của tôi) hoặc đã xuống khi yêu cầu được thực hiện hoặc bị chấm dứt trong khi yêu cầu là với máy chủ ứng dụng (JBoss trong trường hợp của tôi) . – RedYeti

+0

Đối với những gì nó có giá trị: Chấm dứt yêu cầu giữa máy chủ ứng dụng (tôi giữ nó trên một breakpoint) trả lại cho tôi một tình trạng 502 trong khi nếu máy chủ ứng dụng không chạy khi tôi thực hiện yêu cầu tôi nhận được 503 (máy chủ HTTP đang chạy cả hai thời gian của khóa học). – RedYeti

11

Đây là một điều khó khăn để xử lý chính xác trong mọi tình huống. Thật không may trong nhiều trình duyệt phổ biến là xhr.status là giống nhau (0) nếu cuộc gọi AJAX bị hủy bởi điều hướng hoặc máy chủ bị hỏng/không hồi đáp.Vì vậy, kỹ thuật đó hiếm khi hoạt động.

Đây là một tập hợp các hacks "thực tế" rất cao mà tôi đã tích lũy hoạt động khá tốt trong phần lớn các trường hợp, nhưng vẫn không phải là bằng chứng chống đạn. Ý tưởng là cố gắng nắm bắt các sự kiện điều hướng và thiết lập một cờ được kiểm tra trong trình xử lý lỗi AJAX. Như thế này:

var global_is_navigating = false; 

$(window).on('beforeunload',function() { 
    // Note: this event doesn't fire in mobile safari 
    global_is_navigating = true; 
}); 

$("a").on('click',function() { 
    // Giant hack that can be helpful with mobile safari 
    if($(this).attr('href')) { 
     global_is_navigating = true; 
    } 
}); 

$(document).ajaxError(function(evt, xhr, settings) { 
    // default AJAX error handler for page 
    if(global_is_navigating) { 
     // AJAX call cancelled by navigation. Not a real error 
     return; 
    } 
    // process actual AJAX error here. 
}); 
+1

Cảm ơn các giải pháp, chỉ cần nhận thấy một lỗi đánh máy trong mã. Ở cuối mã, dấu ngoặc đơn và dấu chấm phẩy bị thiếu. Vì vậy, phương pháp cuối cùng sẽ như thế này. '$ (document) .ajaxError (function (evt, XHR, cài đặt) { \t // mặc định AJAX lỗi handler cho trang if (global_is_navigating) {// AJAX gọi hủy bỏ bởi điều hướng. Không phải là một lỗi lại được thực ; } }); ' –

+0

Sửa lỗi chính tả, cảm ơn! – Leopd

+0

FYI, giải pháp cho phiên bản di động của Safari vẫn cần thiết cho iOS 10 –

0

Nếu bạn thực hiện sử dụng các hàm jQuery như $.get, $.post, $.ajax ... sau đó bạn có thể sử dụng tham số text_status để kiểm tra những gì loại Fail là:

request = $.get('test.html', function(data){ 
    //whatever 
}).fail(function(xhr, text_status, error_thrown) { 

    if(text_status!== 'abort'){ 
     console.warn("Error!!"); 
    } 
}); 

Từ các jQuery docs:

jqXHR.fail (function (jqXHR, textStatus, errorThrown) {}); Một cấu trúc thay thế cho tùy chọn gọi lại lỗi, phương thức .fail() thay thế phương thức .error() không dùng nữa. Tham khảo deferred.fail() cho chi tiết triển khai.

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