在Symfony2中,我尝试将http缓存用于少数几天返回相同内容的ajax调用。
我的控制器代码完成:
$response = new JsonResponse($data);
$response->setPublic();
$response->setExpires(new \DateTime("+1 hour"));
$response->setMaxAge(3600);
return $response;
在响应中(来自Firefox或IE11),我可以找到预期的标题。但它总是返回200代码(OK)而不是304(未修改)。这意味着服务器总是生成响应,而我的目标是使我的服务器负载不足。
我也尝试使用相同结果的@Cache注释。
如何让它发挥作用?
答案 0 :(得分:2)
您可以通过在app.php中使用AppCache内核(用PHP编写的反向代理)使symfony返回304响应
@Controller
@RequestMapping(produces = {"application/json; charset=UTF-8","*/*;charset=UTF-8"})
public class MyController{
...
}
在制作时,您应该考虑使用真正的反向代理服务器,例如Varnish。
答案 1 :(得分:2)
通过在响应中添加LastModified
标头,我成功缓存了您的示例响应。
我做以下两件事:
<强> 1。将Symfony配置为反向代理
我创建了一个自定义环境,在web文件夹中,我创建了一个名为app_cache的文件。如下所述here in the doc:
#web/app_cache.php
<?php
// web/app.php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
require_once __DIR__.'/../app/AppCache.php';
use Symfony\Component\HttpFoundation\Request;
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
// wrap the default AppKernel with the AppCache one
$kernel = new AppCache($kernel);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
<强> 2。在响应中添加Last Modified标头
我使用这个控制器:
/**
* @Route("/cache-me", name="cacheme")
*/
public function cacheMeAction(Request $request)
{
$data = array("hello" => "symfony");
$response = new JsonResponse($data);
$response->setPublic();
$response->setExpires(new \DateTime("+1 hour"));
$response->setLastModified(new \DateTime("-1 hour"));
return $response;
}
第3。测试强>
我清除prod环境的缓存(app/cache -e=prod
)并使用我的浏览器向网址发出两个请求:
第一次返回200 Ok而第二次304未修改
希望这个帮助
答案 2 :(得分:0)
另一种方法是在控制器中使用cache
服务手动缓存数据,然后执行常见的操作,例如查询数据库和获取内容,只检查是否已存在缓存数据,然后将此数据发送给用户。通常的东西,并在缓存中保存新鲜数据。 JsonResponse
类在此处获取状态代码的第二个参数,您可以手动设置304
$cache = $this->container->get( 'cache' );
$cache_key = 'trafficfeed';
if ( $cache->contains( $cache_key ) ) {
$data = $cache->fetch($cache_key );
/** here $data is a cached data */
/** Response::HTTP_NOT_MODIFIED => 304*/
$response = new JsonResponse($data,Response::HTTP_NOT_MODIFIED);
return $response;
}
/** Fetch fresh data and save in cache */
$cache->save( $cache_key, $data, 3600 );
$response = new JsonResponse($data);
对于缓存服务,您需要在配置
中定义它services:
cache:
class: Doctrine\Common\Cache\PhpFileCache
arguments: [%kernel.cache_dir%]