HTTP缓存

场景

index.php页面里获取Jack的信息。使用demo_cache.php模拟数据库

# 页面demo_cache.php
return [
    'username' => 'jack',
    'age' => 18,
    'blog' => 'www.aipanshi.com'
];
# 页面index.php
<?php
header("Content-type:text/html;charset=utf-8");
$data = require('demo_cache.php');

foreach( $data as $key=>$value ){
    echo $key.'---'.$value;
    echo '<hr>';
}
$curr_time = date('Y-m-d H:i:s');
echo '服务器时间:<span style="color:blue">'.$curr_time.'</span>';
echo '<hr>';
?>
<a href="index.php" target="_blank">点击在新的页面打开</a>

一、使用Cache-Control控制缓存

max-age=[秒] — 执行缓存被认为是最新的最长时间。类似于过期时间,这个参数是基于请求时间的相对时间间隔,而不是绝对过期时间,[秒]是一个数字,单位是秒:从请求时间开始到过期时间之间的秒数。
s-maxage=[秒] — 类似于max-age属性,除了他应用于共享(如:代理服务器)缓存
public — 标记认证内容也可以被缓存,一般来说: 经过HTTP认证才能访问的内容,输出是自动不可以缓存的;
private在服务器设置了private比如:Cache-Control:private, max-age=60的情况下,表示只有用户的浏览器可以缓存private响应,不允许任何中继Web代理对其进行缓存 – 例如,用户浏览器可以缓存包含用户私人信息的HTML网页,但是CDN不能缓存。
no-cache — 强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。这对于需要确认认证应用很有用(可以和public结合使用),或者严格要求使用最新数据的应用(不惜牺牲使用缓存的所有好处);
no-store — 不做缓存
must-revalidate — 告诉缓存必须遵循所有你给予副本的新鲜度。使用缓存的时候每次必须发送请求到服务器校验,比如通过If-Modified-Since或If-None-Match
proxy-revalidate — 和 must-revalidate类似,除了他只对缓存代理服务器起作用,举例:Cache-Control: max-age=3600, must-revalidate

在上述index.php第5行代码添加:

//用Cache-Control告诉浏览器有效期 5秒
header("Cache-Control:max-age=5");//等同于Cache-Control:public, max-age=5

总结:第一次请求成功后,每次点击【点击在新的页面打开】浏览器都会打开一个新的窗口,窗口里的内容在5秒内都是浏览器中的缓存,而不是从服务器获取,5秒后再点击,才重服务器上重新获取最新数据

二、使用响应头Expires控制缓存

在上述index.php第5行代码添加:

//设置10秒的有效期,时间格式是GMT
//时间是当前服务器时间 + 10秒
$expires = gmdate('D, d M Y H:i:s', time() + 10) . ' GMT';
header("Expires:$expires");

总结:第一次请求成功后,每次点击【点击在新的页面打开】浏览器都会打开一个新的窗口,窗口里的内容在10秒内都是浏览器中的缓存,而不是从服务器获取,10秒后再点击,才重服务器上重新获取最新数据

整理

1、expires的弊端是有效期是以服务器时间来设置,如果客户端的时间和服务端时间有一定的时间差,缓存的控制就有问题了,所以还是建议使用Cache-Control好!

2、Cache-Control(支持) 和 expires 同时设置有效期,以 Cache-Control设置的有效期为准

3、上面的两个例子,刷新F5例外

三、通过HTTP 304: Not Modified 使用缓存

访问服务器,根据服务器响应来获取内容。Last-Modified,Etagmust-revalidate 等有些特殊,不直接受浏览器影响,它们必须访问服务器后,再由服务器判断是直接发送新的资源,还是发送一个304 Not Modfied让浏览器使用缓存中的资源

ETag全称Entity Tag,用来标识一个资源。ETag可以是一个hash值或是一个内部维护的版本号。ETag能反映出资源内容的变化,这是http缓存可以正常工作的基础。

Last-Modified的原理其实和ETag差不多,Last-Modified通过时间来标识资源。通过这样的方式可以不必每次都获取全部的资源达到更新的目的,能极大的节省服务器的开销,更有利于搜素引擎的抓取

代码demo

index.php

<?php
header("Content-type:text/html;charset=utf-8");

header("Cache-Control:no-cache");
//响应头Last-Modified
$lastmodified = filemtime('demo_cache.php');
$lastmodifiedGMT = gmdate('D, d M Y H:i:s',$lastmodified). ' GMT';
header("Last-Modified:$lastmodifiedGMT");

//响应头ETag
$etag = md5_file('demo_cache.php');
header("ETag:$etag");

if (@$_SERVER['HTTP_IF_MODIFIED_SINCE'] == $lastmodifiedGMT ||
    @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
        header("HTTP/1.1 304 Not Modified");
        exit;
    }

$data = require('demo_cache.php');

foreach( $data as $key=>$value ){
    echo $key.'---'.$value;
    echo '<hr>';
}
$curr_time = date('Y-m-d H:i:s');
echo '服务器时间:<span style="color:blue">'.$curr_time.'</span>';
echo '<hr>';
?>
<a href="index.php" >点击在新的页面打开</a>

 

posted @ 2020-07-01 21:42  成文的博客  阅读(96)  评论(0编辑  收藏  举报