浏览器缓存机制 php,浏览器缓存机制

在我们开发网站的时候往往对网站的性能有极高的需求,当然,外包的除外哈.我见过的外包对效率要求特别高.对代码质量以及性能要求都不是很高.所以这里就不说明太多.高性能就意味着要使用各式各样的缓存,后台redis/memcached缓存等,前台就是浏览器缓存.什么是浏览器缓存.简单来说,就是浏览器继续使用从服务器上的内容,而不去使用服务器上的内容.那如何使用呢,在使用之前,我们先来讲讲浏览器刷新机制.

浏览器刷新

常见的浏览器刷新有如下几个,Ctrl+F5,Ctrl+R,F5,还有个就是转到,前进.不要认为前进就不是刷新了.其实这个是错误的.下面我们来讲讲这几个区别.

Ctrl + F5:

这个在开发过程中,经常使用,为什么说呢,Ctrl+F5为强制刷新,让浏览器不遵守缓存协议,强制的全部重新在服务器上去请求.所有资源都全部重新的去请求.

Ctrl + R|F5:

让浏览器遵守缓存协议,例如last-modified,etag等这些.如果这是服务端返回的是304就认为没有修改,就会直接调用之前的内容.具体的等下面在讲解.用户最多的操作

前进->:

还有类似于这种操作,就是输入浏览器直接回车.浏览器会将代码Expires的并且没有过期的全部使用,以最少的请求去请求浏览器.就不用担心这种也是强制刷新了.

下面我们就来讲讲一些常见的用了浏览器缓存的例子.

Last-modified

在我们浏览网站的时候,经常能看到这个头部信息,这个头部信息是用来记录最后一次的修改时间.如果网站响应的头部信息有这个,那么下次访问的时候,浏览器会带上一个这样的标识

If-Modified-Since:时间

然后服务端可以根据这个来判断是不是应该可以直接使用缓存.当然,一般动态的网页是很少用这种的,因为不存在传统意义上的最后的修改时间.一般会用于静态网站长时间不修改文件的内容等.我们来做一个简单示例.

// 判断是否含有这个最后一次修改时间,如果有,就强制使用304,让浏览器使用缓存.并终止程序.

if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {

header('HTTP/1.1 304 Not Modified');

exit;

}

// 添加最后一次的修改时间

header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');

echo date('Y-m-d H:i:s');

这里的做法虽然并不合理,没有判断时间,只要存在就使用缓存.这仅仅是为了看下效果,开发程序时应该有更好的做法.让我们来看看效果.我们把这个命令成index.php,放在localhost执行的地址,让我们来看看

1460000014823626?w=655&h=896

第一次访问,浏览器得到的last-modified这个响应头,我们来看看请求头和响应头

--Response Headers--

Connection:keep-alive

Content-Encoding:gzip

Content-Type:text/html; charset=UTF-8

Date:Fri, 11 May 2018 02:19:51 GMT

Last-Modified:Fri, 11 May 2018 01:37:15 GMT

Server:nginx/1.9.15 (Ubuntu)

Transfer-Encoding:chunked

--Request Headers--

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Encoding:gzip, deflate, br

Accept-Language:zh-CN,zh;q=0.9

Cache-Control:no-cache

Connection:keep-alive

Host:localhost

Pragma:no-cache

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36

从上面可以看出,对于第一次访问的网站,浏览器并没有缓存.然后当我们再次使用了F5过来,在来看看

1460000014823627?w=825&h=806

这里我们的程序代码是直接退出程序,没有任何输出,那为什么还有这个输出,这个正式因为浏览器读取自己的缓存.让我们看看响应头.

--Response Headers--

Connection:keep-alive

Date:Fri, 11 May 2018 02:26:57 GMT

Server:nginx/1.9.15 (Ubuntu)

这里仅有简单的几行,指明了web服务器和系统,再来看看请求头

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Encoding:gzip, deflate, br

Accept-Language:zh-CN,zh;q=0.9

Cache-Control:max-age=0

Connection:keep-alive

Host:localhost

If-Modified-Since:Fri, 11 May 2018 01:37:15 GMT

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36

添加了一个If-Modified-Since,让我们来判断有效期,这个就是让我们来判断是否使用浏览器缓存的一个标识.所以这个就让我们的浏览器强制使用了缓存.

Etag

这个头又是用来干嘛的,这个又是跟浏览器协商的另一种方法,它于前面的last-modified非常相似,但是它没有用文件的最后修改时间,而是用一段编码俩标记内容,这个编码并没有强制要求,但是我们通常用一个文件内容的md5来作为Etag.一个原则就是,如果一个内容的Etag没有变化,那么这个内容也一定没有更新.让我们来弄一个简单的示例.

$date = date('Y-m-d'); // 我们这里用当前的日期来代替文件md5

// 判断请求头中是否存在if-none-match,如果存在就去判断md5,如果值一样,就返回304

if (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)

&& $_SERVER['HTTP_IF_NONE_MATCH'] == 'W/"' . md5($date) . '"') {

header('HTTP/1.1 304 Not Modified');

exit; // 退出

}

// 添加请求头.

header('Etag: "' . md5($date) . '"');

echo date('Y-m-d H:i:s');

这里我们的程序代码是跟我们用last-modified是一样的.对于我们来说,也是不合理的,只是用来当成示例而已方便理解.让我们来看看执行效果.

1460000014823628

第一次都是强制请求,如果前面的没有处理,就先Ctrl+F5,这里就先说明这个.具体的部署还是跟上一步的步骤一样.让我们看看响应头

--Response Headers--

Connection:keep-alive

Content-Encoding:gzip

Content-Type:text/html; charset=UTF-8

Date:Fri, 11 May 2018 02:45:07 GMT

Etag:W/"64ddf4c4fbf56a689c963872a8325370"

Server:nginx/1.9.15 (Ubuntu)

Transfer-Encoding:chunked

在响应头里面增加一项,Etag,当然这个是我们的程序输出的.用程序控制的.我们来看看F5过后的结果

1460000014823629?w=750&h=815

我们看见响应头中多了一个If-None-Match这个跟我们上一个请求的Etag值是一样的.

--Request Headers--

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Encoding:gzip, deflate, br

Accept-Language:zh-CN,zh;q=0.9

Cache-Control:max-age=0

Connection:keep-alive

Host:localhost

If-None-Match:W/"64ddf4c4fbf56a689c963872a8325370"

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36

这个对于我们来说,在程序中我们也是直接停止了,并且报出304的状态码,但是浏览器还是作出反映了,将以前的值拿过来用了.这个就是我们的Etag

Etag和Last-Modified

既然这两个都是用来作用浏览器缓存的.那谁的优先级高呢,其实没有优化级,根据我们服务的处理来的.我们如果优先处理Etag那就Etag值高,优先处理Last-Modified就Last-Modified高.

另一种不同的Expires

上面两种方式已经说明了,但是我们还是会经常看到,在我们退出浏览器过后,再次访问这个网站的时候,还是读取的缓存.显然,我们上面两种都不行的.不信你试试.这里我们就介绍另外一种,Expires,我们先来例子

$stream = file_get_contents('./etag-1.png');

$seconds_to_cache = 3600;

$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";

header('Content-Type: image/png');

header("Expires: $ts");

echo $stream;

当我们第一次访问的时候,用localhost访问时,会得到一张图片.并且缓存1个小时,然后我们退出浏览器.并修改代码

exit('111111');

$stream = file_get_contents('./etag-1.png');

$seconds_to_cache = 3600;

$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";

header('Content-Type: image/png');

header("Expires: $ts");

echo $stream;

然后在访问时,依然会得到我们的图片,并没有得到我们所谓的6个1.这个图片已经被浏览器缓存下来了.Expires是绝对时间.同理还有一个相对的,Cache-Control这里我就不演示,可以自己根据代码来作出演示即可.

最后

我们根据以上的得出如下结果

Last-Modified -> If-Modified-Since // 浏览器缓存于当前会话

Etags -> If-Modified-Since // 浏览器缓存当前会话

Expires // 关闭后也有效

Cache-Control // 关闭后也有效

我们可以根据不同的场景应用不同的缓存机制了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值