Symfony4中isXmlHttpRequest返回结果异常问题求助
解决Symfony4中浏览器返回按钮触发错误Ajax判断的问题
兄弟,我太懂这种莫名其妙的坑了!你遇到的这个问题根源其实是浏览器缓存在搞鬼——当你从谷歌点击返回按钮时,浏览器并没有真正向你的Symfony服务器发起新请求,而是直接从本地缓存里读取了上次Ajax请求返回的JSON内容,导致Symfony的isXmlHttpRequest()判断逻辑完全没机会执行,直接返回了缓存的结果。
为什么会这样?
浏览器对于GET请求(不管是直接访问还是普通Ajax请求)会做缓存优化,尤其是通过后退/前进按钮访问历史记录时,它会默认优先使用缓存的响应,以此提升加载速度。这就导致你的控制器根本没收到新请求,自然没法正确判断当前是普通访问还是Ajax请求。
几个靠谱的解决方案
方案一:给响应添加缓存控制头,强制浏览器不缓存
在你的控制器里,不管是返回视图还是JSON响应,都加上禁止缓存的HTTP头,让浏览器每次都必须重新请求服务器:
// 返回视图时 $response = $this->render('your_template.html.twig'); // 添加强制不缓存的头信息 $response->headers->add([ 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0' ]); return $response; // 返回JSON时 $jsonResponse = new JsonResponse($your_data); $jsonResponse->headers->add([ 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0' ]); return $jsonResponse;
这样浏览器就不会保存任何响应缓存,每次后退回来都会发送新请求,Symfony就能正确执行判断逻辑了。
方案二:给Ajax请求添加专属标识,增强判断鲁棒性
可以让你的Ajax请求带上一个特定的查询参数(比如?ajax=1),然后在控制器里同时判断这个参数和isXmlHttpRequest(),双重保险:
if ($request->isXmlHttpRequest() || $request->query->get('ajax')) { // 处理Ajax请求,返回JSON return new JsonResponse($your_data); } else { // 普通访问,返回视图 return $this->render('your_template.html.twig'); }
这种方式即使缓存偶尔搞怪,只要是普通访问(没有ajax参数),控制器就会返回视图,避免误判。
方案三:改用POST请求处理Ajax
浏览器通常不会缓存POST请求的响应,所以你可以把Ajax请求改成POST类型,同时在控制器里限定请求方法:
/** * @Route("/your-target-url", methods={"GET", "POST"}) */ public function yourAction(Request $request) { if ($request->isMethod('POST') && $request->isXmlHttpRequest()) { // POST类型的Ajax请求,返回JSON return new JsonResponse($your_data); } else { // GET请求(普通访问),返回视图 return $this->render('your_template.html.twig'); } }
这样当你从谷歌后退回来时,浏览器会重新发送GET请求,自然就会返回视图了。
个人推荐
最稳妥的方式是方案一+方案二结合,既解决缓存问题,又给判断逻辑加个双重保险,基本上能杜绝这类奇怪的缓存问题。
内容的提问来源于stack exchange,提问作者kironet
相关产品推荐
相关产品推荐

