Symfony2 Form with CSRF passed through JQuery AJAX

15,932

Try with the adequate JQuery function: submit() ^^ In my solution I suppose that your form has the id "comment_form". Works on all my sf2 projects:

$('#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;

});

The CSRF Field would normally be sent !

And don't forget to add the twig tag {{ form_rest(form) }} in your form template, that will generate all hidden field like CSRF.

Share:
15,932
Rich
Author by

Rich

Use the following on a daily basis: Freelance HTML CSS Javascript (JQuery framework) PHP (Symfony/Doctrine framworks mostly) MySQL Wordpress Linux/Mac/Apache Plus these at my day job ASP.NET C# MS SQL IIS SSIS/SSRS

Updated on June 26, 2022

Comments

  • Rich
    Rich almost 2 years

    I am developing a comments box that will save the comment through a JQuery AJAX call.

    JQuery

    Here's the JQuery code for that (this works seamlessly):

    $(".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

    The Symfony2 controller method then picks up the form data and processes it. As part of that process it checks to see if the form is valid:

    $entry = new Discussion();
    $discussionForm = $this->createForm(new DiscussionType(), $entry);
    
    if ($request->getMethod() == 'POST') {
    
        $discussionForm->bindRequest($request);
    
        if ($discussionForm->isValid()) {
    

    This check is not returning true. In the else I extract what error messages have been given and get:

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

    The CSRF token is being passed via post just as it would if the form was submitted synchronously.

    Another possible issue.. Unique Form Id's

    The form I am using is created by a form type class. On any given page there will be several comments forms. As symfony2 uses the getName() method of the type class to populate the forms ID attribute, I have modified it like so:

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

    This allows multiple comments forms without the same id e.g. discussionForm20, discussionForm21, discussionForm22 etc.

    I could remove the symfony2 Form component from the mix and generate the form / process the submission using standard PHP logic but I'm resisting that for now.

    Does anyone know why the forms CSRF token is invalid? Any suggestions on how this could be modified or how you do it?

  • Żabojad
    Żabojad over 10 years
    the JQuery submit method isn't important here. What makes it work is that the $.ajax call takes the all form data serialized in the data parameter.