大话PHP缓存头
304的请求机制和200有什么不一样呢?在fiddler中查看304请求的时候突然想到这个问题,就想到研究下这个304请求机制了。
我们自己在nginx上放一个文件,test.png。可以使用下面的地址进行访问:
http://test.yejianfeng.com/test.png
nginx配置文件如下:
这个的etag关闭是由于nginx默认是开启etag的,说明见ngx_http_core_module(http://nginx.org/en/docs/http/ngx_http_core_module.html)。
现在我把etag关闭了,这个test.png的HTTP请求如下:
可以看到这里的Response Header 中Last-Modified并没有设置过期,所以Last-Modified是不生效的。加上没有其他的相关缓存头,这个时候,浏览器就没有缓存这个页面了。所以呢,不管你黏贴URL,F5 还是Ctrl F5,页面进行的请求Cache-Control都是设置no-cache,所以服务端响应都是200。
下面,修改nginx配置,增加一个expires 1d:
重启nginx,HTTP请求如下:
可以看出这里的Expires比Date多一天,所以就是服务端告诉客户端,你给我在本地缓存一天吧。
那么这个时候使用F5:
返回的就是304了,这个时候,就是本地浏览器缓存了这个页面,发送条件请求给服务端,条件请求里面带一个If-Modified-Since,客户端询问服务端,这个文件浏览器这边有缓存,如果你服务端的文件在这个时间点有更改,就发送一个更改后的文件给我,没有的话就发送一个304就好。
这里还有个问题,这个Last-Modified是怎么定的呢?它就是这个文件在服务器上的最后修改时间。
图中的15:31和last-Modified的07:31中间的8个小时是时区导致的。
我们touch来修改这个文件的最后修改时间:
然后再F5下这个URL:
服务端返回200了,而且Last-Modified也修改了。这个就很好理解了。
如果我不是使用F5,而是将url直接贴到浏览器呢?这个时候,浏览器的行为就是如果本地有缓存,就使用本地的缓存,如果本地没有缓存,就请求服务端。
我们可以做的实验是这样:
1 开启fiddler
2 ctrl + F5,这个时候fiddler中多了一个200响应
3 F5,这个时候fiddler中多了一个304响应
4 打开一个新标签,在地址栏输入url:http://test.yejianfeng.com/test.png 这个时候会发现fiddler并没有任何请求
5 ctrl + F5,这个时候fiddler多一个200响应
所以这里可以验证之前的文章:HTTP缓存相关头(http://www.cnblogs.com/yjf512/p/3244882.html)里面说的三种刷新的行为。
回到缓存头,清空浏览器的缓存,把expire的设置去掉,把etag打开
第一次访问:
看到这里使用ETag了,ETag就相当于一个版本号,HTTP协议中并没有规定etag的算法,它的具体计算就依靠web服务器自身了。ETag还有普通和弱ETag的区分(http://en.wikipedia.org/wiki/HTTP_ETag)。
第二次访问的时候:
客户端发送请求中有个If-None-Match,表示客户端询问服务端,如果你这边的这个文件的tag还是XXXXX,就返回304吧,不是的话就返回200。
所以If-None-Match + ETag是可以控制文件在浏览器中的缓存的。
关于缓存的头,有些是客户端的:
Cache-Control
If-Modified-Since
If-None-Match
有些是服务端的:
Expire
Last-Modified
ETag
相关这些头的说明可以看这篇:HTTP缓存相关头(http://www.cnblogs.com/yjf512/p/3244882.html)
好了,下面说一种情景:
我们再nginx中做了一个rewrite,所有的js都重写到myjs.php这个脚本,那么问个问题,js在F5的时候会发送条件请求,这个条件请求是不是会触发php呢?
答案是会的。条件请求也是一个普通的php请求,它会在触发php的。这个时候如果你需要返回304的话,就需要你在php程序中对If-modified或者If-None-Match进行判断了。
本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/p/3860028.html,如需转载请自行联系原作者

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Scala Trait
Scala Trait 大多数的时候,Scala中的trait有点类似于Java中的interface。正如同java中的class可以implement多个interface,scala中的calss也可以extend多个trait。因此你看你会看到类似于这样的代码: class Woodpecker extends Bird with TreeScaling with Pecking scala的trait具有比java中的interface强大的多的功能,正如同java中的abstract class可以具有一些方法实现一样,scala中的trait也可以拥有implemented methods。但是和java中的abstract class不相同的是,你可以将多个trait糅合到一个class中,也可以控制哪些class可以将trait糅合进去。 trait BaseSoundPlayer { def play def close def pause def stop def resume } 如果方法不需要任何的参数的话,那么就可以使用def只declare方法的名字,而不...
- 下一篇
class org.springframework.core.type.classreading.ClassMetadataReadingV...
今天在工作中遇到了下面的问题: java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99) ~[spring-test-4.0.5.RELEASE.jar:4.0.5.RELEASE] at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101) ~[spring-test-4.0.5.RELEASE.jar:4.0.5.RELEASE] at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDepen...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS关闭SELinux安全模块
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库