2012-12-09 20 views
8

Sto tentando di inviare un modulo di accesso usando ajax. Sono confuso su come dovrei gestire le eccezioni/le risposte positive. Ricevo un 200 OK dal server e il modulo restituisce l'errore sia dal campo password/nome utente. Come posso ottenere un messaggio di errore per visualizzare o reindirizzare l'utente alla pagina appropriata in base alla risposta del server?Modulo di login di 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 }); 

VISTA: AGGIORNATO

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))  

MODULO:

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>   

risposta

8

Anche se è sicuramente una buona pratica fare questo con un json, puoi andartene senza, presumendo che non stai passando davvero molte informazioni dal server. Sul lato django, scambia lo HttpResponseRedirect per un HttpResponse utilizzando l'URL di reindirizzamento come messaggio. Aggiungere anche un HttpResponseForbidden per il caso in cui l'accesso ajax fallisce.

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)) 

Quindi, sul lato javascript, controllare il codice di stato della risposta. Se è 200, allora questo è il tuo HttpResponse - vuoi reindirizzare all'url nel messaggio di risposta. Se si tratta di un 403, allora questo è il tuo HttpResponseForbidden - login non è riuscito. Puoi farla franca con un messaggio di errore standard di "accesso non riuscito".

$.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'); 
    }, 
}); 

Ho paura di non averlo provato, ma dovrebbe darvi un'idea.

Per ulteriori informazioni, consultare docs for django's HttpResponse objects. Quindi controlla il jquery ajax docs.

+1

Vale la pena notare che dovrai assicurarti di essere gestito il token csrf correttamente o avrai problemi con i moduli ajax - https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#ajax –

+0

Grazie Aidan! Ha funzionato. Ora l'unica cosa che devo capire è come analizzare il valore "successivo" dalla risposta in modo da poter reindirizzare correttamente la pagina. :) – user1462141

+0

Non dovrebbe essere necessario l'analisi, mi aspetterei che sia una stringa (non so senza vedere come è stata impostata).La mia ipotesi è che non ci sia un attributo "next" nei dati POST o GET, quindi viene utilizzato il valore predefinito "/". Dovrai scoprire come viene impostato. Controlla qui i documenti per maggiori informazioni sulla richiesta.Registro DOMANDA - https://docs.djangoproject.com/en/1.4/ref/request-response/#django.http.HttpRequest.REQUEST –

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

Ovviamente non si può usare che se si sta eseguendo ajax, il client deve essere responsabile del reindirizzamento/visualizzazione/di qualunque cosa venga inviata di nuovo nella risposta Ajax. Se l'accesso ha esito positivo, invia una risposta JSON che comunica al client di reindirizzare sé stesso (con reindirizzamento javascript), in caso contrario, invia una risposta JSON con l'elenco degli errori e visualizzali utilizzando javascript.

+0

HttpResponseRedirect è una risposta http con un codice di stato 301. Il codice di stato è facilmente accessibile a un oggetto XMLHttpRequest javascript (o alla funzione jQuery ajax). Potrebbe non essere la migliore pratica (non lo so), ma non ha senso dire che "ovviamente non puoi" usare l'header http per passare queste informazioni al client. –

+0

OK, il mio male, ho fatto un po 'di ulteriore lettura, e sembra che i 300 codici non sono accessibili come gli altri codici di stato http sono (come il redirect XMLHttpRequest prima di tornare e fornisce il codice di stato associato al reindirizzamento url). Continuo a non pensare che sia giusto dire che "ovviamente non puoi" usare HttpResponseRedirect. (@camus se vuoi apportare una piccola modifica alla tua risposta rimuoverò il mio voto negativo - Non sono autorizzato a farlo a meno che la risposta non cambi) –

Problemi correlati