带有 CSRF 的 Symfony2 表单通过 JQuery AJAX 传递

Posted

技术标签:

【中文标题】带有 CSRF 的 Symfony2 表单通过 JQuery AJAX 传递【英文标题】:Symfony2 Form with CSRF passed through JQuery AJAX 【发布时间】:2012-02-18 14:58:22 【问题描述】:

我正在开发一个 cmets 框,它将通过 JQuery AJAX 调用保存评论。

JQuery

这是用于此的 JQuery 代码(可以无缝运行):

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

Symfony2 控制器方法然后拾取表单数据并处理它。作为该过程的一部分,它会检查表单是否有效:

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

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

    $discussionForm->bindRequest($request);

    if ($discussionForm->isValid()) 

此检查未返回 true。在 else 中,我提取了给出的错误消息并得到:

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

CSRF 令牌通过 post 传递,就像同步提交表单一样。

另一个可能的问题..唯一表单 ID

我使用的表单是由表单类型类创建的。在任何给定的页面上都会有几个 cmets 表格。由于 symfony2 使用类型类的 getName() 方法来填充表单 ID 属性,所以我将其修改如下:

public function getName()

    return 'discussionForm' . $randomNumber;

这允许没有相同 id 的多个 cmets 表单,例如讨论表单20、讨论表单21、讨论表单22等

我可以从组合中删除 symfony2 表单组件并使用标准 php 逻辑生成表单/处理提交,但我现在拒绝这样做。

有人知道为什么表单 CSRF 令牌无效吗?关于如何修改或如何修改的任何建议?

【问题讨论】:

【参考方案1】:

尝试使用适当的 JQuery 函数:submit() ^^ 在我的解决方案中,我假设您的表单的 id 为“comment_form”。适用于我所有的 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;

);

通常会发送 CSRF 字段!

不要忘记在表单模板中添加树枝标签 form_rest(form) ,这将生成所有隐藏字段,如 CSRF。

【讨论】:

JQuery 提交方法在这里并不重要。使它起作用的是 $.ajax 调用采用数据参数中序列化的所有表单数据。

以上是关于带有 CSRF 的 Symfony2 表单通过 JQuery AJAX 传递的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 - 重载注册表单导致 CSRF 错误(添加 github repo)

symfony2 CSRF 无效

Symfony 2 在使用没有类的表单时添加 CSRF 令牌

在 ajax 提交时禁用 symfony 2 csrf 令牌保护

Symfony2 防止多个表单提交

在登录表单上禁用 CSRF 令牌