HTTP缓存验证
编辑本页HTTP缓存验证
当需要在对底层数据进行更改后立即更新资源时,过期模型就不适用了。与失效模式,应用程序将不会被要求返回更新后的响应,直到缓存最终失效。
的验证模型解决这个问题。在此模型下,缓存继续存储响应。不同之处在于,对于每个请求,缓存都会询问应用程序缓存的响应是否仍然有效,或者是否需要重新生成。如果缓存是仍然有效,您的应用程序应该返回一个304状态代码,没有内容。这将告诉缓存可以返回缓存的响应。
在此模型下,只有在能够通过执行以下操作确定缓存的响应仍然有效时才能节省CPU少工作,而不是重新生成整个页面(参见下面的实现示例)。
提示
304状态代码表示“未修改”。这很重要,因为有了这个状态代码,响应就会这样做不包含被请求的实际内容。相反,响应仅由响应头组成,响应头告诉缓存它可以使用其存储的内容版本。
和过期一样,有两种不同的HTTP头可以用来实现验证模型:ETag
而且last - modified
.
使用ETag
头
的HTTP ETag("entity-tag")报头是一个可选的HTTP报头,其值是唯一标识目标资源的一种表示的任意字符串。它完全由您的应用程序生成和设置,因此您可以判断,例如,如果/对
由缓存存储的资源与应用程序将返回的内容是最新的。
一个ETag
类似于指纹,用于快速比较资源的两个不同版本是否等效。就像指纹一样ETag
必须在同一资源的所有表示形式中惟一。
要查看简短的实现,请生成ETag
随着md5
内容如下:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src /控制器/ DefaultController.php名称空间应用程序\控制器;使用ob娱乐下载\包\FrameworkBundle\控制器\AbstractController;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;类DefaultController扩展AbstractController{公共函数主页(请求$请求):响应{$响应=$这->呈现(“静态/ homepage.html.twig”);$响应->setEtag (md5 ($响应->getContent ()));$响应->setPublic ();//确保响应是public/cacheable$响应->isNotModified ($请求);返回$响应;}}
的isNotModified ()方法比较具有
标头的ETag
响应头。如果两者匹配,则该方法自动设置响应
状态代码是304。
请注意
当使用mod_deflate
或mod_brotli
在Apache 2.4中ETag
值被修改(例如如果ETag
是喷火
,阿帕奇把它变成foo-gzip
或foo-br
),从而打破ETag
的验证。
控件可以控制此行为DeflateAlterETag而且BrotliAlterETag指令。或者,您可以使用以下Apache配置来保留两个原始文件ETag
以及压缩响应时修改的响应:
1
RequestHeader编辑“具有”“^”((. *),(gzip | br))”“美元" $ 1 "," $ 2 "'
请注意
缓存设置具有
的请求上的头ETag
这是缓存和服务器之间相互通信的方式,并决定资源是否已经更新,因为它被缓存。
这个算法很有效,而且非常通用,但是你需要创建一个整体响应
才能计算ETag
,这是次优的。换句话说,它节省了带宽,但没有节省CPU周期。
在HTTP缓存验证部分,您将看到如何更智能地使用验证来确定缓存的有效性,而不需要做这么多工作。
提示
ob娱乐下载Symfony也支持weakETag
S传递真正的
的第二个参数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 /控制器/ ArticleController.php名称空间应用程序\控制器;/ /……使用应用程序\实体\文章;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;类ArticleController扩展AbstractController{公共函数显示(文章$文章,请求$请求):响应{$作者=$文章->getAuthor ();$articleDate=新\ DateTime ($文章->getUpdatedAt ());$authorDate=新\ DateTime ($作者->getUpdatedAt ());$日期=$authorDate>$articleDate?$authorDate:$articleDate;$响应=新反应();$响应->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 /控制器/ ArticleController.php名称空间应用程序\控制器;/ /……使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;类ArticleController扩展AbstractController{公共函数显示(字符串$articleSlug,请求$请求):响应{//获取要计算的最小信息// ETag或Last-Modified值//(基于请求,数据从//数据库或键值存储)$文章=……;//创建一个带有ETag和/或Last-Modified报头的响应$响应=新反应();$响应->setEtag ($文章->computeETag ());$响应->setLastModified ($文章->getPublishedAt ());//设置响应为public。否则默认为私有。$响应->setPublic ();//检查给定请求的响应是否被修改如果($响应->isNotModified ($请求)) {//立即返回304响应返回$响应;}//在这里做更多的工作——比如检索更多的数据$评论=……;//或者用你已经开始的$response来呈现一个模板返回$这->呈现(“文章/ show.html.twig”, (“文章”= >$文章,“评论”= >$评论),$响应);}}
当响应
不是修改过的吗isNotModified ()
自动将响应状态代码设置为304
,删除内容,并删除一些必须不显示的标题304
反应(见setNotModified ()).