Symfony6中Ajax请求失败时实现页面重定向与Flash消息展示
解决方案
核心问题是前端强制将所有响应解析为JSON,但后端失败时返回的是302重定向(最终指向HTML页面),导致JSON解析报错。要解决这个问题,需要让后端统一返回JSON格式响应,在失败时告知前端执行重定向,具体修改如下:
1. 修改后端控制器代码
将失败分支的redirectToRoute改为返回包含重定向URL的JSON响应,同时保留addFlash设置错误消息(会话中的Flash消息会在跳转后的页面生效):
if($request->get('ajax') == 'ajoutPerso' && $request->get('idperso') !== null && $request->get('idpartie') !== null){ $partie = $partieRepository->findOneById($request->get('idpartie')); $perso = $persoRepository->findOneById($request->get('idperso')); $tableauClasses = $classeRepository->findClassesInPartie($partie); if ($partie->getPersos()->count() < 4 && $partie->getOrganisateur() == $user && !(in_array($perso->getClasse()->getId(), $tableauClasses)) && $perso->getPartie() == null) { $partie->addPerso($perso); $em->persist($partie); $em->flush(); return new JsonResponse(['content' => $this->renderView('partie/_persosAjoutes.html.twig', [ 'persosAjoutes' => $partie->getPersos() ])]); } else { $this->addFlash('danger', 'L\'ajout du personnage ne s\'est pas passé comme prévu.'); // 生成目标路由的URL并返回JSON $redirectUrl = $this->generateUrl('app_partie'); return new JsonResponse(['redirect' => $redirectUrl]); } }
2. 修改前端script.js代码
在处理响应时,先判断JSON中是否包含redirect字段,如果有则执行页面跳转;否则正常更新DOM:
function ajouterPerso(){ const IdPerso = this.parentNode.id; const IdPartie = document.querySelector('.recherchePersos').id; const Url = new URL(window.location.href); fetch(Url.pathname + '?idperso=' + IdPerso + '&idpartie=' + IdPartie + '&ajax=ajoutPerso', { headers: { "X-Requested-With": "XMLHttpRequest" } }) .then(response => { // 先检查响应状态是否正常 if (!response.ok) { throw new Error('请求失败'); } return response.json(); }) .then(data => { // 判断是否需要重定向 if (data.redirect) { window.location.href = data.redirect; return; } // 正常更新页面内容 const content = document.querySelector('.persosAjoutes'); content.innerHTML = data.content; this.parentNode.remove(); }) .catch(e => alert(e)); }
为什么这样做?
- 后端统一返回JSON格式,避免前端因响应类型不符导致解析错误;
- Flash消息存储在用户会话中,跳转后的页面可以正常读取并显示;
- 前端根据后端返回的指令决定是更新DOM还是跳转,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Easrim
相关产品推荐
相关产品推荐

