HTTP缓存验证

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 2.7,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

HTTP缓存验证

当需要在对底层数据进行更改后立即更新资源时,过期模型就不适用了。与失效模式,应用程序将不会被要求返回更新后的响应,直到缓存最终失效。

验证模型解决了这个问题。在此模型下,缓存继续存储响应。不同之处在于,对于每个请求,缓存都会询问应用程序缓存的响应是否仍然有效,或者是否需要重新生成。如果缓存仍然有效,您的应用程序应该返回一个304状态代码,没有内容。这将告诉缓存可以返回缓存的响应。

在此模型下,只有在能够通过执行以下操作确定缓存的响应仍然有效时才能节省CPU工作,而不是重新生成整个页面(参见下面的实现示例)。

提示

304状态代码表示“未修改”。这很重要,因为有了这个状态代码,响应就会这样做包含被请求的实际内容。相反,响应只是一组轻量级的方向,告诉缓存它应该使用它存储的版本。

和过期一样,有两种不同的HTTP头可以用来实现验证模型:ETag而且last - modified

当然,您可以同时使用验证和过期响应.由于过期胜过验证,您可以轻松地从两个世界的优点中受益。换句话说,通过使用过期和验证,您可以指示缓存提供缓存的内容,同时以一定的时间间隔(过期)进行检查,以验证内容是否仍然有效。

提示

您还可以使用注释为过期和验证定义HTTP缓存头。看到FrameworkExtraBundle文欧宝体育电话档

使用ETag

ETag标头是一个字符串标头(称为“entity-tag”),唯一标识目标资源的一种表示。它完全由您的应用程序生成和设置,因此您可以判断,例如,如果/对由缓存存储的资源与应用程序将返回的内容是最新的。一个ETag类似于指纹,用于快速比较资源的两个不同版本是否等效。就像指纹一样ETag必须在同一资源的所有表示形式中惟一。

要查看一个简单的实现,生成ETag作为内容的md5:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src / AppBundle /控制器/ DefaultController.php名称空间AppBundle控制器使用欧宝娱乐app下载地址组件HttpFoundation请求DefaultController扩展控制器公共函数homepageAction(请求请求响应->呈现(“静态/ homepage.html.twig”);响应->setEtag (md5 (响应->getContent ()));响应->setPublic ();//确保响应是public/cacheable响应->isNotModified (请求);返回响应;}}

isNotModified ()方法比较具有标头的ETag响应头。如果两者匹配,则该方法自动设置响应状态代码是304。

请注意

缓存设置具有的请求上的头ETag这是缓存和服务器之间相互通信的方式,并决定资源是否已经更新,因为它被缓存。

这个算法非常简单,而且非常通用,但是您需要创建整个算法响应才能计算ETag,这是次优的。换句话说,它节省了带宽,但没有节省CPU周期。

HTTP缓存验证部分,您将看到如何更智能地使用验证来确定缓存的有效性,而不需要做这么多工作。

提示

欧宝娱乐app下载地址Symfony还通过传递支持弱ETags真正的的第二个参数setEtag ()方法。

使用last - modified

last - modified报头是验证的第二种形式。根据HTTP规范,“thelast - modified报头字段指示原始服务器认为表示最后修改的日期和时间。”换句话说,应用程序根据缓存响应后缓存的内容是否已经更新来决定缓存的内容是否已经更新。

属性的值,可以使用计算资源表示所需要的所有对象的最新更新日期last - modified头的值:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/ / src / AppBundle /控制器/ ArticleController.php名称空间AppBundle控制器/ /……使用欧宝娱乐app下载地址组件HttpFoundation响应使用欧宝娱乐app下载地址组件HttpFoundation请求使用AppBundle实体文章ArticleController扩展控制器公共函数showAction(文章文章,请求请求作者文章->getAuthor ();articleDate\ DateTime (文章->getUpdatedAt ());authorDate\ DateTime (作者->getUpdatedAt ());日期authorDate>articleDate?authorDatearticleDate响应反应();响应->setLastModified (日期);//设置响应为public。否则默认为私有。响应->setPublic ();如果响应->isNotModified (请求)) {返回响应;}/ /……做更多的工作来填充响应的完整内容返回响应;}}

isNotModified ()方法比较if - modified - since标头的last - modified响应头。如果它们相等,则响应将被设置为304状态码。

请注意

缓存设置if - modified - since的请求上的头last - modified这是缓存和服务器之间相互通信的方式,并决定资源是否已经更新,因为它被缓存。

使用验证优化代码

任何缓存策略的主要目标都是减轻应用程序的负载。换句话说,在应用程序中返回304响应的操作越少越好。的回应::isNotModified ()方法通过公开一个简单而有效的模式来做到这一点:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/ / src / AppBundle /控制器/ ArticleController.php名称空间AppBundle控制器/ /……使用欧宝娱乐app下载地址组件HttpFoundation响应使用欧宝娱乐app下载地址组件HttpFoundation请求ArticleController扩展控制器公共函数showActionarticleSlug,请求请求//获取要计算的最小信息// ETag或Last-Modified值//(基于请求,数据从//数据库或键值存储)文章=……;//创建一个带有ETag和/或Last-Modified报头的响应响应反应();响应->setEtag (文章->computeETag ());响应->setLastModified (文章->getPublishedAt ());//设置响应为public。否则默认为私有。响应->setPublic ();//检查给定请求的响应是否被修改如果响应->isNotModified (请求)) {//立即返回304响应返回响应;}//在这里做更多的工作——比如检索更多的数据评论=……;//或者用你已经开始的$response来呈现一个模板返回->呈现(“文章/ show.html.twig”数组“文章”= >文章“评论”= >评论),响应);}}

响应不是修改过的吗isNotModified ()自动将响应状态代码设置为304,删除内容,并删除一些必须不显示的标题304反应(见setNotModified ()).

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。