浏览器缓存机制浅解

浏览器的缓存机制:

  • 1: 浏览器会在第一次请求完服务器后获得响应, 咱们能够在服务器中设置这些相应,
    从而达到在之后的请求中尽可能减小甚至不从服务器获取资源的目的。
  • 2: 浏览器缓存中涉及到的头信息
    浏览器的缓存是依靠请求和响应中的的头信息来控制缓存的。html

    1: expires
    最简单的过时缓存方式, 在第一次请求时返回的头信息中设置一个exires时间,在后面的请求的时候, 请求会带着这个expires时间, 假如在这个expires时间内,浏览器不会向服务器发送请求, 而是直接从本地缓存副本中读取数据数据库

    2:Cache-Control
    他有一些不一样的值对应不一样的缓存策略,这里我查到一个,参考一下初探 HTTP 1.1 Cache 機制
    这里要说明的是Cache-Control的设置会覆盖expires的设置, 并且常与Last-Modified和Etag配合使用segmentfault

    3:Last-Modified/Last-Modified-Since
    在使用这个缓存策略的时候, 浏览器每次都会向服务器发送请求, 但服务器能够根据Last-Modified-Since向浏览器返回200或者304, 若是返回304, 就是告诉浏览器让它直接从客户端电脑的缓存中读取副本吧, 不然就会把请求的资源以200的方式返回给浏览器。浏览器

    这里也要说明一下, Last-Modified是浏览器第一次向服务器请求以后, 服务器响应中设置的(即代码中设定), 而Last-Modified-Since则是浏览器每次向服务器请求的时候带着的Last-Modified的值, 好比第一次请求后响应的Last-Modified的值是A, 那么在后面每次请求的时候的Last-Modified-Since的值就是A, 直到服务器从新设置了Last-Modified的值缓存

    4: Etag/If-None-Match
    ETag是一种与Last-Modified/Last-Modified-Since相似的控制方式。用户在第一次请求的时候服务器能够本身生成或由用户生成, 而后响应给浏览器, 那么在之后的请求中,会带着If-None-Match, 它的值就是以前生成的Etag。 在服务器中对比服务器上的Etag与If-None-Match, 假如相同, 则返回304, 不然请求并返回服务器资源。服务器

    这里有一个问题, 如何生成Etag, 尤为是动态页面中, 假如资源发生变化, Etag要从新生成。 我这里想到一种方式, 请求到服务器后, 仍是要进行必要的代码运行, 在代码中, 拿到相关的变量生成一个Etag值, 对比传递上来的If-None-Match, 再断定返回的状态值。(原谅个人经验有限, 这只是一种方式,若是各位有新的思路, 欢迎加入讨论)。函数

    5: Cache-Control/Expires的优先级要高于Last-Modified/Etag,Cache-Control/Expires是控制浏览器是否向服务器拉资源, Last-Modified/Etag是服务器控制是否返回一个完整的请求资源,仍是返回一个304, 假如本地连请求都不会拉, 那Last-Modified/Etag就无从谈起了.post

实现:

下面使用PHP分别实现以上几种缓存方式, 通常服务器上的静态文件都会默认使用Last-Modified/Last-Modified-Since,
因此不少的静态文件在二,三,四。。。次刷新的时候都是304状态(Not Modified).

另外下面的过时时间都是格林威治时间才行,可使用gmdate函数获取。
/*
      Last-Modified/Last-Modified-Since
      我想这里若是用一些数据保存方式,如memcache或数据库, 把某个文件的修改时间保存起来, 若是文件修改了, 则更新这个数据, 而后每次刷新这里的这个页面的时候,先读取修改时间,  若是传递的$lastModifiedSince修改时间不符, 则从新读取, 不然返回304
      测试的结果是在在缓存时间内返回304
     */

     $cacheTime = 60;
     $lastModifiedSince = strtotime(@$_SERVER['HTTP_IF_MODIFIED_SINCE']);
     if($lastModifiedSince + $cacheTime > time())
     {
       header("HTTP/1.1 304"); 
       die('use cache');
     }
     header('Last-Modified: '.gmdate('D d M Y H:i:s', time()).' GMT');
     echo time();


/*
    Etag/If-None-Match
    测试的结果是在服务器上的资源未发生变化时返回的304
*/

    $user_id = 1;
    $etag = md5($user_id);


    $matchEtag = @$_SERVER['HTTP_IF_NONE_MATCH'];

    if($matchEtag == $etag)
    {
        header("HTTP/1.1 304");
        die('use cache');
    }

    header('Etag: '.$etag);
    echo time();

问题:

在测试expires和Cache-Control的max-age的时候, 本地缓存无效, 每次仍是发起请求, 并无读取缓存, 不知为什么?
请看链接测试

PS: 文章中可能有错误的地方, 若是发现, 请及时指出code

相关文章
相关标签/搜索