2013-07-25 28 views
20

Có mã trạng thái HTTP để hướng dẫn khách hàng thực hiện lại yêu cầu đó không?Mã trạng thái HTTP để thử lại yêu cầu tương tự

Tôi đang gặp phải tình huống máy chủ phải "chờ" để khóa biến mất khi xử lý yêu cầu. Nhưng do thời gian khóa biến mất, các yêu cầu có thể gần với giới hạn thời gian chờ của nó. Vì vậy, thay vào đó, khi khóa bị xóa, tôi muốn hướng dẫn khách hàng thực hiện lại yêu cầu đó.

Điều tốt nhất tôi đưa ra là HTTP 307 đến cùng một vị trí, nhưng tôi lo lắng rằng một số trình duyệt có thể không mua vào (phát hiện vòng lặp chuyển hướng).

+1

Thêm thông số URL thay đổi, do đó, nó sẽ không có vẻ giống như một vòng lặp. – Barmar

+0

Câu trả lời hay cho http://stackoverflow.com/q/9794696/520567 (202 và 423) – akostadinov

Trả lời

24

Phản hồi chính xác khi máy chủ không thể xử lý yêu cầu là 503 Service Unavailable. Khi điều kiện là tạm thời, như trong trường hợp của bạn, bạn có thể đặt tiêu đề Retry-After để cho khách hàng biết phải đợi bao lâu trước khi thử lại.

Tuy nhiên, điều này sẽ không buộc trình duyệt thực hiện lại yêu cầu - đây là thứ bạn cần phải tự xử lý trong javascript. Ví dụ, đây là cách bạn có thể thực hiện một yêu cầu POST thử lại ajax trong jquery:

function postData() { 
    $.ajax({ 
    type: 'POST', 
    url: '503.php', 
    success: function() { 
     /* 
     Do whatever you need to do here when successful. 
     */ 
    }, 
    statusCode: { 
     503: function(jqXHR) { 
     var retryAfter = jqXHR.getResponseHeader('Retry-After'); 
     retryAfter = parseInt(retryAfter, 10); 
     if (!retryAfter) retryAfter = 5; 
     setTimeout(postData, retryAfter * 1000); 
     } 
    } 
    }); 
} 

Lưu ý rằng đoạn mã trên chỉ hỗ trợ một tiêu đề Retry-After nơi trì hoãn thử lại được quy định trong vài giây. Nếu bạn muốn hỗ trợ những ngày cần nhiều công việc hơn một chút. Trong mã sản xuất, tôi cũng khuyên bạn nên truy cập một số loại để đảm bảo bạn không tiếp tục thử lại mãi mãi.

Đối với việc sử dụng mã trạng thái 307 để tự động lặp lại yêu cầu, tôi không nghĩ đó là một ý tưởng hay. Ngay cả khi bạn thêm tham số thử lại để phát hiện xung quanh phát hiện vòng lặp của trình duyệt (cảm giác giống như một hack khủng khiếp), nó vẫn không hoạt động trên yêu cầu POST. Từ RFC2616:

Nếu mã trạng thái 307 được nhận để phản hồi yêu cầu không phải GET hoặc HEAD, tác nhân người dùng PHẢI KHÔNG tự động chuyển hướng yêu cầu trừ khi người dùng có thể xác nhận.

Mặc dù một số trình duyệt được biết là bỏ qua yêu cầu này, nhưng chắc chắn không chính xác và không phải là thứ bạn muốn dựa vào.

Và nếu bạn không sử dụng yêu cầu POST, bạn gần như chắc chắn sẽ như vậy. Hãy nhớ rằng yêu cầu GET should not have any side effects và theo mặc định, phản hồi sẽ được lưu vào bộ nhớ cache. Từ mô tả của vấn đề của bạn, nó có vẻ rất giống như yêu cầu của bạn có khả năng được làm một cái gì đó có tác dụng phụ.

+0

Tôi không nghĩ rằng lỗi máy chủ là một câu trả lời đúng ở đây. Đối với tôi một cái gì đó trong phạm vi 4xx sẽ có ý nghĩa hơn. Tôi đọc http://stackoverflow.com/q/9794696/520567 - có 423 là một lựa chọn tốt cho trường hợp sử dụng ops. Ngoài ra 202 là tốt cho các trường hợp sử dụng khác. – akostadinov

3

Sử dụng 307 redirect, nhưng thêm một retry truy cập:

http://path/to/server?retry=3 

này sẽ làm cho các URL khác nhau trên mỗi thử lại, ngăn chặn phát hiện vòng lặp. Và máy chủ có thể kiểm tra xem thử lại có đạt đến giới hạn hay không và hủy bỏ khi có lỗi xảy ra, vì vậy người dùng không chờ đợi mãi mãi.

+0

Tôi không nghĩ chuyển hướng HTTP cho phép sửa đổi các tham số? Lưu ý rằng 307 phải làm việc cho bất kỳ phương pháp nào. Vì vậy, nếu yêu cầu ban đầu là POST với 'form-data/multipart', tôi không nghĩ mình có thể thêm tham số' retry'? – Jeroen

+0

Bạn có thể chuyển hướng đến bất kỳ URL nào và nó có thể chứa thông số, vậy tại sao chúng không khác với các thông số ban đầu?Nhưng bạn nói đúng rằng điều này sẽ không hoạt động với POST - nó sẽ không đăng lại biểu mẫu lên URL mới. – Barmar

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