在 Symfony 5 中验证 AJAX 提交的表单
Posted
技术标签:
【中文标题】在 Symfony 5 中验证 AJAX 提交的表单【英文标题】:Validation of AJAX submitted forms in Symfony 5 【发布时间】:2021-02-19 04:09:36 【问题描述】:我正在 Symfony 5.1 中构建一个 Address
表单。
它是在具有一些必填字段的AddressType
类中创建的。
$builder
->add('name', TextType::class, [
'required' => false,
'label' => 'address.name',
'help' => 'address.name_help',
'attr' => [
'placeholder' => 'address.name_ph',
]
])
->add('company', TextType::class, [
'required' => false,
'label' => 'address.company',
'attr' => [
'placeholder' => 'address.company_ph',
]
])
->add('first_line', TextType::class, [
'label' => 'address.first_line',
'attr' => [
'placeholder' => 'address.first_line_ph',
]
])
->add('second_line', TextType::class, [
'required' => false,
'label' => 'address.second_line',
'attr' => [
'placeholder' => 'address.second_line_ph',
]
])
->add('add_info', TextType::class, [
'required' => false,
'label' => 'address.add_info',
'help' => 'address.add_info_help',
'attr' => [
'placeholder' => 'address.add_info_ph',
]
])
->add('postcode', TextType::class, [
'label' => 'address.postcode',
'attr' => [
'placeholder' => 'address.postcode_ph',
]
])
->add('city', TextType::class, [
'label' => 'address.city',
'attr' => [
'placeholder' => 'address.city_ph',
]
])
->add('state', TextType::class, [
'required' => false,
'label' => 'address.state',
'attr' => [
'placeholder' => 'address.state_ph',
]
])
->add('country', CountryType::class, [
'label' => 'address.country',
'preferred_choices' => ['FR'],
'attr' => [
'data-toggle' => 'select',
'placeholder' => 'address.country_ph',
]
])
->add('save',
SubmitType::class,
[
'label' => $options['submit_btn_label'],
]
);
如果我使用提交按钮提交此表单,一切都会按预期工作,我的表单正在处理以进行验证,如果它检测到一些错误,它们会显示在每个字段上。
这是处理表单的函数:
public function new(Request $request)
$user = $this->getUser();
$address = new Address();
$address->setCreatedBy($user);
$form = $this->createForm(AddressType::class, $address);
//handle form
$form->handleRequest($request);
if ($form->isSubmitted())
//if submit, add hidden fields
$address = $form->getData();
//if valid, process
if ($form->isValid())
$em = $this->getDoctrine()->getManager();
$em->persist($address);
$em->flush();
$this->addFlash(
'success',
'Your address was created.'
);
return $this->redirectToRoute('address_index');
return $this->render('address/new.html.twig', [
'form' => $form->createView(),
'mode' => 'new',
]);
现在,如果我通过 AJAX 请求提交此表单:
$(document).on('click', '.create-address', function()
console.log('submitting new address form...');
var $form = $(this).closest('form')
var data = $form.serializeArray();
$.ajax(
url : $form.attr('action'),
type: $form.attr('method'),
data : data
);
);
在这种情况下,我的表单被处理以进行验证并且它通过了($form->isValid()
返回true
),即使我没有提供一些必填字段。
这会导致持久化对象的过程发生,因此我得到一个 PDOException。
我的问题是: 为什么我的表单处理方式不同(尤其是在验证步骤)根据我发布数据的方式? 从处理请求的函数的角度来看,这两种方法有什么不同?
【问题讨论】:
【参考方案1】:required
option 仅将required
属性添加到标记中。这会强制浏览器提供一个值,但不会添加任何验证服务器端。您可以在 ajax 调用之前trigger validation 并仅在表单状态有效时提交。
但建议通过在表单中使用constraints
选项或注释目标实体来显式添加服务器端验证。详情请参考to the documentation。
【讨论】:
感谢您回答@msg。我了解必需属性和约束之间的区别。实体Address
定义有一些约束,例如不可为空。
好吧,其实我误解了约束和ORM规则的区别。 (我有针对不可空字段的 ORM 规则,我认为这对于验证来说是不够的/等效的)。谢谢
@Corentoulf 我正要问这个。但是,从 4.3 开始,它们应该是 automatically generated。
哼.. 所以这是一种奇怪的行为吧?无论如何添加约束“强制”验证。
@Corentoulf 我发现最好是明确的,所以我通常会添加它们而不依赖于该功能,所以我不能肯定地告诉你,可能是回归。你能检查你是否安装了symfony/property-info
所需的依赖项吗? (我认为你应该,这只是好奇)。以上是关于在 Symfony 5 中验证 AJAX 提交的表单的主要内容,如果未能解决你的问题,请参考以下文章
Symfony3 + Select2 AJAX - 禁用选择验证
带有 RESTful 身份验证的 Symfony2 应用程序,使用 FOSRestBundle 和 FOSUserBundle