2011-08-05 39 views
17

Tôi đang sử dụng jQuery 1.6.2 để thực hiện yêu cầu POST AJAX đến một trang trên cùng một miền. Trang đó thực hiện chuyển hướng 302 đến một trang khác.Trong cuộc gọi AJAX, 302 không được theo dõi

Hiện tại, trên máy cục bộ của tôi hoạt động tốt nhưng trên máy chủ sản xuất của chúng tôi, chuyển hướng không bao giờ được theo dõi và trong trình kiểm tra Chrome, yêu cầu được gọi là 'bị hủy'.

Nếu tôi truy cập vào cùng một trang mà không cần sự tham gia của javascript, mọi thứ hoạt động tốt, và như tôi đã nói AJAX hoạt động trên máy tính cục bộ của tôi, nhưng không phải trên máy chủ sản xuất.

Có ai biết điều gì có thể gây ra điều này không?

Có một số khác biệt giữa các máy chủ (OS X, Apache2, PHP5.3.6, HTTP trên máy cục bộ, Ubuntu, Lighttpd, PHP5.3.3, HTTPS khi sản xuất) nhưng không có gì khác với tôi.

+1

Tôi giả định chuyển hướng 302 sang một tài nguyên khác trên cùng một tên miền? –

+0

Thật vậy. Hóa ra có một lỗi trong kohana mặc dù điều đó khiến cho chuyển hướng trở thành HTTP thay vì HTTPS. Điều đó phải khiến trình duyệt hủy yêu cầu. – Johan

+3

Tuyệt vời. Thêm câu trả lời dưới đây - trong hai ngày, bạn sẽ có thể chấp nhận câu trả lời của mình là câu trả lời đúng để những người có vấn đề tương tự trong tương lai có thể tìm thấy câu trả lời. –

Trả lời

11

Hóa ra một lỗi trong mã chuyển hướng gây ra chuyển hướng đến http: // trong khi trang đó được yêu cầu là https: //. Điều đó làm cho trình duyệt từ chối theo dõi chuyển hướng.

+1

Vì vậy, làm thế nào bạn giải quyết truy vấn của bạn, giống như điều tôi đang phải đối mặt là tốt. –

6
function doAjaxCall() { 
    $.ajaxSetup({complete: onRequestCompleted}); 
    $.get(yourUrl,yourData,yourCallback); 
} 

function onRequestCompleted(xhr,textStatus) { 
    if (xhr.status == 302) { 
     location.href = xhr.getResponseHeader("Location"); 
    } 
} 

các câu hỏi sau liên quan đến câu trả lời của bạn. bạn có thể tìm thấy câu trả lời từ các liên kết bên dưới.

Catching 302 FOUND in JavaScript

How to manage a redirect request after a jQuery Ajax call

+4

Các trình duyệt không được chuyển 302 đến JS, vì trình duyệt xử lý chuyển hướng một cách minh bạch, vì vậy jQuery sẽ không bao giờ biết nó được chuyển hướng. Tôi không rõ liệu đây có phải là tất cả các trình duyệt hay không, tuy nhiên Chrome rõ ràng làm theo cách này và các trình duyệt khác đã báo cáo Opera/FF tương tự. – DanH

+0

'Trình duyệt không được chuyển 302 đến JS' không có nghĩa là bạn phải bỏ phiếu bình chọn. hãy thử mã ở trên bản thân bạn và sau đó đặt câu trả lời đúng nếu điều này là sai thay vì bỏ phiếu mà không biết. và xem 3 upvotes cũng –

+6

'xhr.status == 302' sẽ không bao giờ xảy ra vì 302 sẽ được trình duyệt xử lý, sau đó sẽ chỉ trả lại mã lỗi 200 hoặc mã lỗi khác cho JS, vì vậy tôi xem xét lời khuyên phản tác dụng này . Tôi sẽ xóa -1 tuy nhiên vì bạn liên kết đến các câu hỏi khác. Tôi sẽ cung cấp một câu trả lời khác. – DanH

2

Dựa trên câu trả lời này: https://stackoverflow.com/a/8752354/698289 tôi thấy đoạn mã sau sẽ rất hữu ích:

$('body').ajaxComplete(function (e, xhr, settings) { 
    if (xhr.status == 200) { 
     var redirect = null; 
     try { 
      redirect = $.parseJSON(xhr.responseText).redirect; 
      if (redirect) { 
       window.location.href = redirect; 
      } 
     } catch (e) { 
      return; 
     } 
    } 
}); 

Sau đó, bạn chỉ cần cung cấp JSON như sau:

{redirect: '/redirect/to/this/path'} 

ajaxComplete sẽ đảm bảo để chuyển hướng trình duyệt.

Hãy lưu ý rằng $.ajax('complete') gây SAU $.ajax('success') hoặc $.ajax('error')

+0

Tôi không nghĩ đây là một giải pháp tốt. Nó có nghĩa là tôi phải đặt nó trên mọi trang? Vui lòng sửa tôi nếu tôi hiểu sai. – smwikipedia

+0

Đoạn mã trên là Javascript và do đó sẽ chỉ chạy miễn là nó được tải trong trình duyệt web trên mọi trang được yêu cầu. – DanH

2

Tôi coi đây là một vấn đề server-side, và không client-side. Trình duyệt chính xác không theo các chuyển hướng đến http khi yêu cầu ajax theo số https, vì đó sẽ là một lỗ hổng bảo mật.

Tôi nhận ra mình đang sử dụng tương đối đường dẫn, chẳng hạn như HttpResponseRedirect('/path/to/'). Trên một số lớp, url đã được thêm vào phía trước với tiền tố http:// và đó là những gì mà trình duyệt nhận: http://example.com/path/to/

Bạn phải đảm bảo rằng các Location được gửi trong tiêu đề phản ứng với một đường dẫn đầy đủ, bao gồm cả https://.

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