带有 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)
Symfony 2 在使用没有类的表单时添加 CSRF 令牌