2012-12-09 42 views
8

Tôi đang cố gửi biểu mẫu đăng nhập bằng ajax. Tôi bối rối như thế nào tôi phải xử lý các trường hợp ngoại lệ/phản ứng thành công. Tôi nhận được 200 OK từ máy chủ và biểu mẫu trả về lỗi bằng trường mật khẩu/tên người dùng. Làm thế nào tôi có thể nhận được thông báo lỗi để hiển thị hoặc chuyển hướng người dùng đến trang thích hợp tùy thuộc vào phản hồi của máy chủ?Biểu mẫu đăng nhập Django Ajax

jQuery:

56 $(window).load(function(){                             
57 $('#login_form').submit(function(e){                           
58    e.preventDefault();                            
59  var request_url = document.getElementById('next').value                    
60   $.ajax({                               
61    type:"POST",                              
62    url: $(this).attr('action'),                          
63    data: $('#login_form').serialize(),                        
64    success: function(response){ $('#msg').text(response);                   
65    console.log(response);                           
66    },                                
67    error: function(xhr, ajaxOptions, thrownError){ alert($('#login_error').text('Username already taken. Please select another one.')}, 
68   });                                
69  });                                  
70 }); 

XEM: CẬP NHẬT

51 def login(request):                               
52  if request.method == 'POST':                            
53   request.session.set_test_cookie()                         
54   login_form = AuthenticationForm(request, request.POST)                    
55   if login_form.is_valid():                           
56    if request.is_ajax:                            
57     user = django_login(request, login_form.get_user())                   
58     if user is not None:                           
59      return HttpResponseRedirect(request.REQUEST.get('next', '/')) 
      **else:**                                
61    **return HttpResponseForbidden() # catch invalid ajax and all non ajax**           
60  else:                                 
61   login_form = AuthenticationForm(request)                        
62                                    
63  c = Context({                               
64   'next': request.REQUEST.get('next'),                         
65   'login_form': login_form,                           
66   'request':request,                             
67  })                                  
68  return render_to_response('login.html', c, context_instance=RequestContext(request))  

MẪU:

7 <tt id="login_error"></tt>                                
8 <form id="login_form" action="" method="post">                        
9                                    
10  {{ login_form }}                               
11  <input type="submit" value="login"/>                          
12  <input type="hidden" id="request_path" name="next" value="/"/>                   
13 </form>                                 
14 <p>{{ request.get_full_path }}</p>                           
15 <tt id='msg'></tt>   

Trả lời

8

Mặc dù chắc chắn thực hành tốt hơn để làm điều này với một json, bạn có thể lấy đi mà không có, giả sử bạn không thực sự vượt qua nhiều thông tin trở lại từ máy chủ. Ở phía django, hãy đổi số HttpResponseRedirect cho số HttpResponse bằng cách sử dụng URL chuyển hướng làm thư của bạn. Đồng thời thêm HttpResponseForbidden cho trường hợp đăng nhập ajax không thành công.

def login(request):                               
    if request.method == 'POST':                            
     request.session.set_test_cookie()                         
     login_form = AuthenticationForm(request, request.POST)                    
     if login_form.is_valid():                           
      if request.is_ajax:                            
       user = django_login(request, login_form.get_user())                   
       if user is not None:                           
        return HttpResponse(request.REQUEST.get('next', '/')) 
     return HttpResponseForbidden() # catch invalid ajax and all non ajax               
    else:                                 
     login_form = AuthenticationForm()                                   
    c = Context({                               
     'next': request.REQUEST.get('next'),                         
     'login_form': login_form,                               
     'request':request,                             
    })                                  
    return render_to_response('login.html', c, context_instance=RequestContext(request)) 

Sau đó, ở bên javascript, hãy kiểm tra mã trạng thái của phản hồi. Nếu đó là 200, thì đó là số HttpResponse của bạn - bạn muốn chuyển hướng đến url trong thư trả lời. Nếu đó là 403, thì đó là của bạn HttpResponseForbidden - đăng nhập đã thất bại. Bạn có thể nhận được thông báo lỗi 'đăng nhập không thành công' chuẩn.

$.ajax({                               
    type:"POST",                              
    url: $(this).attr('action'),                          
    data: $('#login_form').serialize(), 
    // the success function is called in the case of an http 200 response                     
    success: function(response){ 
     // redirect to the required url 
     window.location = response;                          
    },                                
    error: function(xhr, ajaxOptions, thrownError){ 
     alert('login failed - please try again'); 
    }, 
}); 

Tôi sợ rằng tôi chưa thử nghiệm điều này, nhưng nó sẽ cung cấp cho bạn một ý tưởng.

Để biết thêm thông tin, hãy xem docs for django's HttpResponse objects. Sau đó, xem jquery ajax docs.

+1

Cần lưu ý rằng bạn cần đảm bảo rằng bạn đang xử lý mã thông báo csrf đúng cách hoặc bạn sẽ gặp sự cố với biểu mẫu ajax - https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#ajax –

+0

Cảm ơn Aidan! Nó đã làm việc. Bây giờ điều duy nhất tôi cần phải tìm ra là làm thế nào để phân tích giá trị 'tiếp theo' từ phản hồi để tôi có thể chuyển hướng trang đúng cách. :) – user1462141

+0

Nó không cần phân tích cú pháp, tôi mong đợi nó là một chuỗi (Tôi không biết mà không nhìn thấy nó được thiết lập như thế nào).Tôi đoán là không có thuộc tính 'tiếp theo' trong dữ liệu POST hoặc GET để giá trị mặc định '/' đang được sử dụng. Bạn sẽ cần phải tìm hiểu cách nó được thiết lập. Xem tài liệu tại đây để biết thêm thông tin về yêu cầu.REQUEST từ điển - https://docs.djangoproject.com/en/1.4/ref/request-response/#django.http.HttpRequest.REQUEST –

1
return HttpResponseRedirect(request.REQUEST.get('next', '/')) 

Bạn rõ ràng không thể sử dụng rằng nếu bạn đang làm ajax, khách hàng phải chịu trách nhiệm chuyển hướng/hiển thị/bất cứ điều gì được gửi trở lại trong phản ứng Ajax. Nếu đăng nhập thành công, hãy gửi câu trả lời JSON cho khách hàng tự chuyển hướng (với chuyển hướng javascript), nếu không, hãy gửi câu trả lời JSON với danh sách lỗi và hiển thị chúng bằng javascript.

+0

HttpResponseRedirect là câu trả lời http với mã trạng thái 301. Mã trạng thái rất dễ truy cập đối tượng XMLHttpRequest javascript (hoặc hàm jQuery ajax). Nó có thể không được thực hành tốt nhất (tôi không biết), Nhưng nó là vô nghĩa để nói rằng bạn 'rõ ràng là không thể' sử dụng tiêu đề http để truyền thông tin này cho khách hàng. –

+0

OK, xấu của tôi, tôi đã đọc thêm một chút và có vẻ như 300 mã không thể truy cập giống như các mã trạng thái http khác (như XMLHttpRequest chuyển hướng trước khi trở về và cung cấp mã trạng thái được liên kết với chuyển hướng url). Tôi vẫn không nghĩ rằng nó là đúng để nói rằng bạn 'rõ ràng là không thể' sử dụng HttpResponseRedirect. (@camus nếu bạn muốn thực hiện một thay đổi nhỏ đối với câu trả lời của mình, tôi sẽ xóa phiếu bầu phủ định của mình - Tôi không cho phép thực hiện trừ khi câu trả lời thay đổi) –

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