zoukankan      html  css  js  c++  java
  • 大话PHP缓存头

    304的请求机制和200有什么不一样呢?在fiddler中查看304请求的时候突然想到这个问题,就想到研究下这个304请求机制了。

    我们自己在nginx上放一个文件,test.png。可以使用下面的地址进行访问:

    http://test.yejianfeng.com/test.png

     

    nginx配置文件如下:

    Image

    这个的etag关闭是由于nginx默认是开启etag的,说明见ngx_http_core_module(http://nginx.org/en/docs/http/ngx_http_core_module.html)。

    现在我把etag关闭了,这个test.png的HTTP请求如下:

    Image(1)

    可以看到这里的Response Header 中Last-Modified并没有设置过期,所以Last-Modified是不生效的。加上没有其他的相关缓存头,这个时候,浏览器就没有缓存这个页面了。所以呢,不管你黏贴URL,F5 还是Ctrl F5,页面进行的请求Cache-Control都是设置no-cache,所以服务端响应都是200。

    下面,修改nginx配置,增加一个expires 1d:

    Image(2)

    重启nginx,HTTP请求如下:

    Image(3)

    可以看出这里的Expires比Date多一天,所以就是服务端告诉客户端,你给我在本地缓存一天吧。

    那么这个时候使用F5:

    Image(4)

    返回的就是304了,这个时候,就是本地浏览器缓存了这个页面,发送条件请求给服务端,条件请求里面带一个If-Modified-Since,客户端询问服务端,这个文件浏览器这边有缓存,如果你服务端的文件在这个时间点有更改,就发送一个更改后的文件给我,没有的话就发送一个304就好。

    这里还有个问题,这个Last-Modified是怎么定的呢?它就是这个文件在服务器上的最后修改时间。

    Image(5)

    图中的15:31和last-Modified的07:31中间的8个小时是时区导致的。

    我们touch来修改这个文件的最后修改时间:

    Image(6)

    然后再F5下这个URL:

    Image(7)

    服务端返回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响应

    Image(8)

    所以这里可以验证之前的文章:HTTP缓存相关头(http://www.cnblogs.com/yjf512/p/3244882.html)里面说的三种刷新的行为。

     

    回到缓存头,清空浏览器的缓存,把expire的设置去掉,把etag打开

    Image(9)

    第一次访问:

    Image(10)

    看到这里使用ETag了,ETag就相当于一个版本号,HTTP协议中并没有规定etag的算法,它的具体计算就依靠web服务器自身了。ETag还有普通和弱ETag的区分(http://en.wikipedia.org/wiki/HTTP_ETag)。

    第二次访问的时候:

    Image(11)

    客户端发送请求中有个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进行判断了。

  • 相关阅读:
    PAT 1097. Deduplication on a Linked List (链表)
    PAT 1096. Consecutive Factors
    PAT 1095. Cars on Campus
    PAT 1094. The Largest Generation (层级遍历)
    PAT 1093. Count PAT's
    PAT 1092. To Buy or Not to Buy
    PAT 1091. Acute Stroke (bfs)
    CSS:word-wrap/overflow/transition
    node-webkit中的requirejs报错问题:path must be a string error in Require.js
    script加载之defer和async
  • 原文地址:https://www.cnblogs.com/yjf512/p/3860028.html
Copyright © 2011-2022 走看看