2012-01-25 5 views
15

Sto sviluppando una casella di commenti che salverà il commento attraverso una chiamata JQuery AJAX.Symfony2 Form con CSRF passato attraverso JQuery AJAX

JQuery

Ecco il codice JQuery per quel (questo funziona perfettamente):

$(".post-comment").click(function() { 
    var $form = $(this).closest("form"); 

    if($form) 
    { 
     $.ajax({ 
      type: "POST", 
      url: Routing.generate('discussion_create'), 
      data: $form.serialize(), 
      cache: false, 
      success: function(html){ 
       alert("Success!"); 
       // Output something     
      } 
     }); 
    } 
    else 
    { 
     alert("An error occured"); 
    } 
    return false; 
}); 

Symfony2 controller

Il metodo di controllo di Symfony2 raccoglie quindi il backup dei dati e dei processi di forma esso. Come parte di tale processo controlla se il modulo è valido:

$entry = new Discussion(); 
$discussionForm = $this->createForm(new DiscussionType(), $entry); 

if ($request->getMethod() == 'POST') { 

    $discussionForm->bindRequest($request); 

    if ($discussionForm->isValid()) { 

Questo controllo non restituisce true. Nella altro che estrarre ciò che i messaggi di errore sono stati dati e ottenere:

Array 
(
    [0] => The CSRF token is invalid. Please try to resubmit the form 
) 

Il token CSRF viene passato a mezzo posta proprio come farebbe se il modulo è stato presentato in modo sincrono.

Un altro possibile problema .. è unico modulo di identificazione

La forma che sto usando è stato creato da una classe tipo di modulo. In una data pagina ci saranno diversi moduli di commenti. Come Symfony2 utilizza il metodo getName() della classe tipo per popolare l'attributo ID forme, ho modificato in questo modo:

public function getName() 
{ 
    return 'discussionForm' . $randomNumber; 
} 

Questo consente a più commenti forme senza lo stesso id esempio discussioneForm20, discussioneForm21, discussioneForm22, ecc.

Potrei rimuovere il componente di symfony2 Form dal mix e generare il modulo/processo dell'invio utilizzando la logica PHP standard, ma per ora non ci riesco.

Qualcuno sa perché il token CSRF di moduli non è valido? Qualche suggerimento su come questo potrebbe essere modificato o come lo si fa?

risposta

28

Prova con la funzione JQuery adeguata: submit() ^^ Nella mia soluzione suppongo che il tuo modulo abbia l'id "comment_form". Funziona su tutti i miei progetti sf2:

$('#comment_form').submit(function(e) { 

    var url = $(this).attr("action"); 

    $.ajax({ 
     type: "POST", 
     url: url, // Or your url generator like Routing.generate('discussion_create') 
     data: $(this).serialize(), 
     dataType: "html", 
     success: function(msg){ 

      alert("Success!"); 

     } 
    }); 

    return false; 

}); 

Il campo CSRF sarebbe normalmente inviato!

E non dimenticare di aggiungere il tag ramoscello {{form_rest (form)}} nel modello di modulo, che genererà tutti i campi nascosti come CSRF.

+1

il metodo di invio JQuery non è importante qui. Ciò che lo rende efficace è che la chiamata $ .ajax prende tutti i dati del modulo serializzati nel parametro dei dati. –