让我们考虑如下情况:
我的控制器如下所示:
/**
*
*
* @Route("/ajax", name="ajax_route" , options={"expose"=true})
* @Template()
*/
public function someAction()
{
$request = $this->getRequest();
$json = array( );
if($request->isXmlHttpRequest())
{
$res = json_encode($json);
return new Response($res , 200 , array( 'Content-Type' => 'application/json' ));
}
return array( );
}
换句话说,如果用户按下后退按钮,if($request->isXmlHttpRequest())
将返回true,这不是我要查找的结果。这是正常的行为还是什么?
答案 0 :(得分:8)
Symfony\Component\HttpFoundation\Request::isXmlHttpRequest()
是一种简单的实用程序方法,用于检查HTTP请求是否带有值为X-Requested-With
的{{1}}标头。所以它和XMLHttpRequest
标题一样可靠。
然而,这并不重要。需要注意的重要事项是,当用户点击后退按钮时,浏览器会不向服务器发送新的HTTP请求。它只是从内部内存/缓存中恢复页面。
答案 1 :(得分:4)
我知道这是一个老问题,但同样的问题引起了我的注意,所以我想我还是会写一个答案。
在大多数情况下,您可以通过将onUnload处理程序附加到窗口来使后退按钮缓存无效,如下所示:
window.addEventListener('unload',function(){});
或者,如果您更喜欢jQuery:
$(window).unload(function(){});
但是,由于你的AJAX响应是JSON,显然不可能,因为你不能包含脚本片段。在这种情况下,我认为最好的想法是设置cache-control: no-store
标题,以便浏览器不会尝试缓存结果。
你可以使用Symfony2在OP的情况下使用:
return new Response($res , 200 , array(
'Content-Type' => 'application/json',
'Cache-Control' => 'no-store',
));
或更一般的PHP:
header('Cache-Control: no-store');
这里有一个警告,它可能会降低你的性能,取决于你的应用程序的结构,在这种情况下,你最好的选择可能只是为你的AJAX调用使用不同的URL。很糟糕,我知道。
您可以在bfcache here上找到一些文档,这些文档在不同情况下可能更有帮助。
答案 2 :(得分:0)
浏览器仅使用url和请求方法(GET,POST等)作为密钥来缓存响应。
如果您希望浏览器识别其他变体,可以通过在响应中设置Vary标头来告知它。因此,在您的情况下,您希望告诉浏览器服务器的响应将根据请求中是否设置了“X-Requested-With”标头而有所不同。
以下是如何操作:
$response = new Response();
$response->setVary("X-Requested-With"); // <=========== Set the Vary header
if($request->isXmlHttpRequest()) {
//...
}
return $response;
注意:您要在两个版本的响应上设置Vary标头(这就是为什么我将它设置在if语句之外)。