2012-01-16 45 views
12

Tôi có nhiều yêu cầu ajax một số dữ liệu yêu cầu mỗi phút khác được khởi tạo bởi người dùng thông qua ui.Làm cách nào để gửi lại yêu cầu ajax không thành công?

$.get('/myurl', data).done(function(data){ 
    // do stuff.. 
}); 

Yêu cầu có thể không thành công do lỗi xác thực. Tôi đã thiết lập phương thức toàn cầu .ajaxError() để bắt mọi yêu cầu không thành công.

$(document).ajaxError(function(e, jqxhr){ 
    // Correct error.. 
}); 

Sau khi tôi gặp lỗi, tôi đặt lại ủy quyền. Đặt lại ủy quyền hoạt động nhưng người dùng phải bắt đầu lại cuộc gọi ajax theo cách thủ công (thông qua ui).

Làm cách nào để gửi lại yêu cầu không thành công bằng cách sử dụng jqxhr ban đầu được gửi?

(Tôi đang sử dụng jQuery cho ajax)

+0

Tôi phải làm điều đó một lần. Tôi chỉ đơn giản là lưu trữ nội dung của đối tượng 'data' gốc * (được chuyển đến phương thức' get') ở đâu đó an toàn và sử dụng lại nó trong một lệnh gọi 'get', được kích hoạt bằng một lần nhấp vào nút' tryry', hoặc một bộ đếm thời gian. –

+1

http://api.jquery.com/jQuery.ajax/ bạn có thể sử dụng '.fail' cùng với' .done' và gọi phương thức gọi lại từ đó. –

+0

@atornblad - Điều này sẽ không giúp đỡ vì đối tượng 'dữ liệu' có thể bị ghi đè bởi một yêu cầu AJAX khác được kích hoạt trước một lỗi' lỗi'. –

Trả lời

11

Tìm thấy this post gợi ý rằng một giải pháp tốt cho vấn đề này

Điều quan trọng là sử dụng $ .ajaxPrefilter và thay thế xử lý lỗi của bạn với một tùy chỉnh để kiểm tra cho lần thử lại và thực hiện một thử lại bằng cách sử dụng 'originalOptions của việc đóng cửa '.

tôi gửi bài mã chỉ trong trường hợp nó sẽ được ẩn trong tương lai, một lần nữa, tín dụng thuộc về the original writer

// register AJAX prefilter : options, original options 
$.ajaxPrefilter(function(options, originalOptions, jqXHR) { 

    originalOptions._error = originalOptions.error; 

    // overwrite error handler for current request 
    options.error = function(_jqXHR, _textStatus, _errorThrown){ 

    if (... it should not retry ...){ 

     if(originalOptions._error) originalOptions._error(_jqXHR, _textStatus, _errorThrown); 
     return; 
     }; 

     // else... Call AJAX again with original options 
     $.ajax(originalOptions); 
    }; 
}); 
+0

viết gì thay vì '... không nên thử lại ...' –

7

Trong trường hợp này, tôi sẽ viết một handler cụ thể đối với các mã 403 tình trạng, có nghĩa là trái phép (máy chủ của tôi sẽ quay trở lại một 403 quá). Từ tài liệu jquery ajax, bạn có thể làm

$.ajax({ 
    statusCode: { 
    403: function() { 
     relogin(onSuccess); 
    } 
    } 
}); 

để đạt được điều đó.

Trong trình xử lý đó, tôi sẽ gọi phương thức relogin, chuyển một hàm chụp những gì cần làm khi đăng nhập thành công. Trong trường hợp này, bạn có thể chuyển vào phương thức chứa cuộc gọi bạn muốn chạy lại.

Trong mã ở trên, relogin nên gọi mã đăng nhập và onSuccess phải là hàm kết thúc mã bạn thực thi mỗi phút.

EDIT- dựa trên làm rõ của bạn trong nhận xét, rằng kịch bản này xảy ra cho nhiều yêu cầu, cá nhân tôi sẽ tạo API cho ứng dụng của bạn nắm bắt tương tác với máy chủ.

app = {}; 
app.api = {}; 
// now define all your requests AND request callbacks, that way you can reuse them 
app.api.makeRequest1 = function(..){..} // make request 1 
app.api._request1Success = function(...){...}// success handler for request 1 
app.api._request1Fail = function(...){...}// general fail handler for request 1 

/** 
    A method that will construct a function that is intended to be executed 
    on auth failure. 

    @param attempted The method you were trying to execute 
    @param args  The args you want to pass to the method on retry 
    @return function A function that will retry the attempted method 
**/ 
app.api.generalAuthFail = function(attempted, args){ 
    return function(paramsForFail){ // whatever jquery returns on fail should be the args 
     if (attempted) attempted(args); 
    } 
} 

như vậy với cấu trúc đó, trong phương pháp request1 của bạn, bạn sẽ làm điều gì đó như

$().ajax({ 
    .... 
    statusCode: { 
     403: app.api.generalAuthFail(app.api.request1, someArgs); 
    } 
}} 

các generalAuthFailure sẽ trả về một callback mà thực hiện phương pháp mà bạn vượt qua trong.

+0

Tôi đã nghĩ đến việc này, vấn đề là tôi có nhiều cuộc gọi ajax, không chỉ một cuộc gọi một lần một phút. Tôi cần một cách để truy cập yêu cầu không thành công từ bên trong lỗi và kích hoạt lại yêu cầu ban đầu. – hitautodestruct

+0

BTW Trong trường hợp của tôi, chúng tôi đang nói về [401] (http://en.wikipedia.org/wiki/HTTP_401#4xx_Client_Error) – hitautodestruct

+0

cho 401, chỉ cần thay đổi số ... – hvgotcodes

0

Bạn có thể có thể đi bằng cách đặt tên cho từng chức năng của bạn và sau đó gọi lại chúng như đã nêu trong các câu trả lời của hvgotcodes.

Hoặc

Bạn có thể sử dụng một chức năng tái sử dụng để thiết lập một yêu cầu trong khi mở rộng giá trị mặc định:

function getRequest(options){ 

    var // always get json 
     defaults = { dataType: 'json' }, 
     settings = $.extend(defaults, options); 


    return // send initial ajax, if it's all good return the jqxhr object 
      $.ajax(settings) 
      // on error 
      .fail(function(jqxhr, e){ 
       // if the users autherization has failed out server responds with a 401 
       if(jqxhr.status === 401){ 
        // Authenticate user again 
        resetAuthentication() 
        .done(function(){ 
         // resend original ajax also triggering initial callback 
         $.ajax(settings); 
        }); 
       } 
      }); 
}; 

Để sử dụng chức năng trên, bạn sẽ viết một cái gì đó như thế này:

getRequest({ 
    url: 'http://www.example.com/auth.php', 
    data: {user: 'Mike', pass: '12345'}, 
    success: function(){ // do stuff } 
}); 

Các getRequest() có thể có thể được thực hiện đệ quy và/hoặc chuyển đổi thành một plugin jQuery nhưng điều này là đủ cho nhu cầu của tôi.

Lưu ý: Nếu chức năng resetAutentication sức faile, getRequest() sẽ phải đệ quy.

1

Đoạn code dưới đây sẽ tiếp tục yêu cầu ban đầu và nó sẽ cố gắng để thành công 3 lần.

var tries = 0; 
$(document).ajaxError(function(event, jqxhr, settings, thrownError) { 
    if(tries < 3){ 
     tries++; 
     $.ajax(this).done(function(){tries=0;}); 
    } 
}); 
+1

cách thức và vị trí bạn tăng giá trị "trys" – kiran

+1

@kiran 'limit' nên được thay thế bằng' trys' cảm ơn bạn :) Tôi sẽ chỉnh sửa ngay bây giờ. –

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