Symfony2 表单通过 JQuery AJAX 传递 CSRF

发布于 2024-12-28 18:37:13 字数 1629 浏览 1 评论 0原文

我正在开发一个评论框,它将通过 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

我正在使用的表单是由表单类型类创建的。在任何给定页面上都会有几个评论表单。由于 symfony2 使用类型类的 getName() 方法来填充表单 ID 属性,我对其进行了如下修改:

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

这允许多个评论表单没有相同的 id,例如discussionForm20、discussionForm21、discussionForm22 等。

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

有谁知道为什么表单 CSRF 令牌无效?关于如何修改或如何做到这一点有什么建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

刘备忘录 2025-01-04 18:37:13

尝试使用适当的 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 字段通常会被发送!

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文