如何在Symfony/Twig中实现页面重载后仍可正常跳转的返回按钮
问题根源
表单提交后触发页面重定向,此时浏览器请求的Referer请求头会被自动设置为当前菜谱页的地址,导致你读取到的来源地址变为当前页,返回按钮就无法回到上一级页面。
解决方案1:前端极简方案(无需修改后端代码,推荐)
直接通过浏览器历史API实现返回,完全不受页面重载影响,也不需要提前获取分类参数,适配你的场景:
修改Twig中的返回按钮代码即可:
<a class="d-block text-decoration-none cursor px-4 pt-3" href="{{ path('home') }}" onclick="if(window.history.length > 1){window.history.back();return false;}"> <img src="{{ asset('build/images/back.svg')}}" class="height-19"> </a>
逻辑说明:如果浏览器有上一页历史就返回上一页,否则兜底跳转到首页,避免用户直接访问菜谱页时点击返回无反应。
解决方案2:后端Session存储方案
如果不想依赖JS,可以将首次进入页面的原始来源存在Session中,后续表单提交后也不会被覆盖:
- 修改控制器逻辑:
public function show(Recipe $recipe,RecipeRepository $recipeRepository,ScoreRepository $scoreRepository,CommentRepository $commentRepository, Request $request): Response { $comment = new Comment(); $score = new Score(); $comment_form = $this->createForm(CommentType::class, $comment); $comment_form->handleRequest($request); $score_form = $this->createForm(ScoreType::class, $score); $score_form->handleRequest($request); $entityManager = $this->getDoctrine()->getManager(); $user = $this->getUser(); // 新增:首次GET请求时存储原始来源 $sessionKey = 'recipe_referrer_' . $recipe->getId(); if ($request->isMethod('GET')) { // 只有首次进入页面时存来源,后续提交表单不更新 if (!$request->getSession()->has($sessionKey)) { $originalReferrer = $request->headers->get('referer', $this->generateUrl('home')); $request->getSession()->set($sessionKey, $originalReferrer); } } // --- 原有评分表单逻辑修改 --- if ($score_form->isSubmitted() && $score_form->isValid()) { $score_value = $score_form->get("score")->getData(); $isScore = $scoreRepository->findBy(array('user' => $user , 'recipe' => $recipe->getId())); if($isScore == [] ){ $score->setScore($score_value); $score->setRecipe($recipe); $score->setUser($user); $entityManager->persist($score); $entityManager->flush(); $this->addFlash('success', '¡Puntuación registrada con exito!'); // 修复原有redirectToRoute传参错误,直接用redirect即可 return $this->redirect($request->getUri()); }else{ $this->addFlash('danger', 'Ya existe una puntuación registrada para esta receta con este usuario.'); return $this->redirect($request->getUri()); } } // 原有评论表单逻辑无需修改 $comments = $commentRepository->findCommentsByRecipe($recipe); return $this->render('recipe/show/show.html.twig', [ 'recipe' => $recipe, 'score_form' => $score_form->createView(), 'comment_form' => $comment_form->createView(), 'comments' => $comments, // 传递原始来源到模板 'original_referrer' => $request->getSession()->get($sessionKey) ]); }
- 修改Twig模板:
<a class="d-block text-decoration-none cursor px-4 pt-3" href="{{ original_referrer }}"> <img src="{{ asset('build/images/back.svg')}}" class="height-19"> </a>
原有代码注意事项
你原有代码里存在两处小错误需要修复:
- 评分提交成功处错误使用
redirectToRoute传入完整URL,redirectToRoute只接受路由名,完整URL跳转需要用redirect方法 - 代码中
$this->request->atrributes拼写错误,正确为attributes
内容的提问来源于stack exchange,提问作者Cristina
相关产品推荐
相关产品推荐

