Ber*_*rdA 5 javascript php ajax jquery symfony
环顾四周后我找不到解决方案。仅当通过 Ajax 提交时,我才会收到以下错误。这意味着我事先已经以常规 Symfony 方式提交了表单,没有出现任何问题。
\n\n\n\n\nCSRF 令牌无效。请尝试重新提交表格。
\n
什么有效:
\n\n\n\n\n$form->submit($request->request->get($form->getName(\'user\')));
\n
根据要求,请参阅下面的输出
\n\n\n\n\nvar_dump($request->request->get($form->getName(\'user\')));
\n
array(8) { \n["name"]=> string(9) "fafdffafa" \n["avatar"]=> string(9) "dfafffafa" \n["cityId"]=> string(1) "6" \n["phone"]=> string(14) "33434343434344" \n["email"]=> array(2) { \n ["first"]=> string(22) "myemail@gmail.com" \n ["second"]=> string(22) "myemail@gmail.com" } \n["plainPassword"]=> array(2) { \n ["first"]=> string(8) "senha444" \n ["second"]=> string(8) "senha444" } \n["blogSubs"]=> string(1) "1" \n["_token"]=> string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }\n
Run Code Online (Sandbox Code Playgroud)\n\n只是为了确认,如果我只是注释掉下面的 JavaScript,提交将起作用并且实体将被持久化。
\n\n这是相同的 var_dump,这次是在工作正常时。
\n\narray(9) { \n["name"]=> string(12) "dfdfdfdfafaf" \n["avatar"]=> string(13) "dfdfdfdafdafa" \n["cityId"]=> string(1) "8" \n["phone"]=> string(16) "3343434343343343" \n["email"]=> array(2) { \n ["first"]=> string(22) "myemail@gmail.com" \n ["second"]=> string(22) "myemail@gmail.com" }\n["plainPassword"]=> array(2) { \n ["first"]=> string(8) "senha444" \n ["second"]=> string(8) "senha444" } \n["blogSubs"]=> string(1) "1" \n["save"]=> string(0) "" \n["_token"]=> string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }\n
Run Code Online (Sandbox Code Playgroud)\n\n这是Symfony生成的提交按钮,但没有被js序列化捕获。
\n\n<button type="submit" id="user_save" name="user[save]" class="btn-default btn">Cr\xc3\xa9er mon compte</button>\n
Run Code Online (Sandbox Code Playgroud)\n\n表单(我跳过了 $builder 表单,因为它似乎没有必要)
\n\n应用程序/资源/视图/common/register.html.twig
\n\n{{ form_start(form, { \'attr\': { \'id\': \'signup_form\' }}) }}\n <div class="contact input-group">\n {{ form_widget(form.name) }}\n </div>\n <div class="contact input-group">\n {{ form_widget(form.avatar) }}\n <span class="input-group-addon" id="info_avatar">\n <i class="fa fa-info"></i>\n </span> \n </div>\n <div class="contact input-group">\n {{ form_widget(form.cityId) }}\n </div>\n <div class="contact input-group">\n {{ form_widget(form.phone) }} \n </div>\n <div class="contact input-group">\n {{ form_widget(form.email) }}\n </div>\n <div class="contact input-group">\n {{ form_widget(form.plainPassword) }}\n </div>\n <div class="contact">\n {{ form_widget(form.blogSubs) }}\n </div>\n <div class="contact form-group ">\n {{ form_widget(form.save) }}\n </div>\n{{ form_end(form) }} \n
Run Code Online (Sandbox Code Playgroud)\n\n同一文件上的 JavaScript:
\n\n<script>\n $(\'body\').on(\'submit\',\'#signup_form\',function(event) {\n event.preventDefault();\n var str = $("#signup_form").serialize();\n $.ajax({\n url: "/inscription",\n type: "POST",\n dataType:"json",\n data: str,\n success: function (data) {\n alert(data);\n } \n });\n });\n </script>\n
Run Code Online (Sandbox Code Playgroud)\n\n和控制器( getErrorMessages() 方法是在 SO 上找到的。)
\n\n/src/UsedBundle/Controller/RegistrationController.php
\n\nnamespace UsedBundle\\Controller;\n\nuse UsedBundle\\Form\\UserType;\nuse UsedBundle\\Entity\\User;\nuse Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Route;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Security\\Core\\Encoder\\UserPasswordEncoderInterface;\nuse Doctrine\\ORM\\EntityManagerInterface;\nuse Symfony\\Component\\HttpFoundation\\JsonResponse;\n\nclass RegistrationController extends Controller\n{\n/**\n * @Route("/inscription", name="inscription")\n */\npublic function registerAction(Request $request)\n{\n $user = new User();\n $form = $this->createForm(UserType::class, $user);\n\n if ($request->isMethod(\'POST\')) {\n var_dump($_POST);\n $form->submit($request->request->get($form->getName(\'user\')));\n if(!$form->isValid()){ \n $errors = $this->getErrorMessages($form);\n var_dump($errors);\n }\n if ($form->isSubmitted() && $form->isValid()) {\n $password = $this->get(\'security.password_encoder\')\n ->encodePassword($user, $user->getPlainPassword());\n $user->setPassword($password);\n $email = $user->getEmail();\n $user->setUserKey( $email );\n $user->setUserKeyTime();\n $user->setDateReg();\n $em = $this->getDoctrine()->getManager(\'used\');\n $em->persist($user);\n $em->flush();\n return new JsonResponse(array(\'message\' => \'Success!\'));\n }\n }else{\n return $this->render(\n \'common/register.html.twig\',\n array(\'form\' => $form->createView())\n ); \n }\n}\n\nprotected function getErrorMessages($form) \n{\n $errors = array();\n foreach ($form->getErrors() as $key => $error) {\n $errors[] = $error->getMessage();\n }\n\n foreach ($form->all() as $child) {\n if (!$child->isValid()) {\n $errors[$child->getName()] = $this->getErrorMessages($child);\n }\n }\n\n return $errors;\n} \n}\n
Run Code Online (Sandbox Code Playgroud)\n
正如评论中所讨论的,您的问题的原因与不同的环境有关。如果您使用带有app_dev.php
前端控制器的标准 Symfony 项目,您的表单将使用环境的有效 csrf 令牌进行渲染dev
。你的 JavaScript 代码
$.ajax({
url: "/inscription",
type: "POST",
dataType:"json",
data: str,
success: function (data) {
alert(data);
}
});
Run Code Online (Sandbox Code Playgroud)
不知道 Symfony 环境,因此 url/location
指向该prod
环境,导致出现 CSRF 令牌无效的错误消息。
要解决此问题,您可以使前端代码了解 Symfony 路由,例如使用FOSJsRoutingBundle。或者您可以禁用环境的 CSRF 保护dev
:
# app/config/config_dev.yml
framework:
csrf_protection: false
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1946 次 |
最近记录: |