You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 13:35:29