Symfony 7.2表单触发RedirectResponse失效问题求助
Symfony 7.2表单触发RedirectResponse跨域问题解决
问题现象
在Symfony 7.2中使用RedirectResponse时出现异常:直接调用重定向(如访问/redirection路由)可正常跳转至外部地址,但通过表单提交触发的重定向却被浏览器拦截,抛出跨域错误。该功能在Symfony 6.4中可正常运行。
错误提示
Cross-Origin Request Blocked: The "Same Origin" policy does not allow viewing the remote resource located at https://example.com/. Reason: The CORS header "Access-Control-Allow-Origin" is missing. Status code: 501.
示例代码
控制器代码
<?php namespace App\Controller; use App\Form\TestType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class TestController extends AbstractController { #[Route(path: '/redirection', name: 'redirection')] public function redirection(): RedirectResponse { return new RedirectResponse('https://example.com'); } #[Route(path: '/formulaire', name: 'formulaire')] public function index(Request $request): RedirectResponse|Response { $form = $this->createForm(TestType::class); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { return new RedirectResponse('https://example.com'); } return $this->render('test.html.twig', [ 'form' => $form, ]); } }
表单类型代码
<?php namespace App\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class TestType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('submit', SubmitType::class, []) ; } public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([]); } }
原因分析
问题根源在于Symfony 7.0+默认集成了Turbo(Hotwire组件),它会自动将表单提交转换为AJAX请求。当服务器返回跨域重定向时,AJAX请求受浏览器同源策略限制,会被拦截并抛出CORS错误;而直接访问路由的请求是普通HTTP请求,浏览器可直接执行跨域跳转,不受同源策略约束。
解决方案
方案1:禁用表单的Turbo行为
让表单以传统方式提交,避免AJAX触发的跨域限制。可在创建表单时添加data-turbo="false"属性:
// 控制器中修改表单创建代码 $form = $this->createForm(TestType::class, null, [ 'attr' => ['data-turbo' => 'false'], ]);
或者在表单类型的buildForm方法中全局设置:
public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('submit', SubmitType::class, []) ->setAttribute('attr', ['data-turbo' => 'false']); }
方案2:保留Turbo并适配跨域重定向
若需保留Turbo的AJAX提交特性,可通过添加Turbo-Location响应头,让Turbo触发浏览器全页面跳转,绕过AJAX的同源限制:
// 控制器中修改重定向代码 if ($form->isSubmitted() && $form->isValid()) { $response = new RedirectResponse('https://example.com'); $response->headers->set('Turbo-Location', 'https://example.com'); return $response; }
内容的提问来源于stack exchange,提问作者AshKusa
相关产品推荐
相关产品推荐

