有篇博文介绍的原理已经比较清楚了,见下面链接, 本文给出实验结果。
http://www.cnblogs.com/cocowool/archive/2011/08/22/2149929.html
Last-modified
第一次请求,请求头中没有 IF_Modify_Since, 因为第一次还没有获得 Last-Modified时间值, 本次请求只能是无条件请求。
GET http://localhost/httpcache.php HTTP/1.1
Host: localhost
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8,en-GB;q=0.6,en;q=0.4
第一次响应, 响应头有 Last-modified值, 浏览器缓存此值,待下次网页访问执行有条件访问, 即将此值作为请求报文头中 If_Modify_Since值。
HTTP/1.1 200 OK
Date: Mon, 16 Jun 2014 16:12:13 GMT
Server: Apache/2.4.7 (Win32) OpenSSL/0.9.8y PHP/5.4.25
X-Powered-By: PHP/5.4.25
Last-modified: Fri, 16 Mar 2007 04:00:25 GMT
Content-Length: 524
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<style></style>
</head>
<body>
<h1>hello world!11</h1>
<input type="text" value="test"/>
<input type="button" value="button"/>
<script type='text/javascript'>
$("[type='button']").click(function(){
$("[type='text']").val("button click");
})
</script>
</body>
</html>
第二次浏览器请求, 带有If-Modified-Since
GET http://localhost/httpcache.php HTTP/1.1
Host: localhost
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8,en-GB;q=0.6,en;q=0.4
If-Modified-Since: Fri, 16 Mar 2007 04:00:25 GMT
第二次响应, 带有304状态,并没有报文体, 则告诉浏览器使用上次缓存。
HTTP/1.1 304 Not Modified
Date: Mon, 16 Jun 2014 16:23:40 GMT
Server: Apache/2.4.7 (Win32) OpenSSL/0.9.8y PHP/5.4.25
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
代码:
<?php $if_mod_since = ""; $headers = getallheaders(); while (list($header, $value) = each($headers)) { if ( "If-Modified-Since" == $header ) { $if_mod_since = $value; break; } } if ( $if_mod_since != "" ) { //告诉浏览器文档内容没有发生改变 header('HTTP/1.1 304 Not Modified'); exit(0); } else { header("Last-modified: Fri, 16 Mar 2007 04:00:25 GMT"); } ?> <html> <head> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <style> </style> </head> <body> <h1>hello world!11</h1> <input type="text" value="test"/> <input type="button" value="button"/> <script type='text/javascript'> $("[type='button']").click(function(){ $("[type='text']").val("button click"); }) </script> </body> </html>
ETAG
与 第一个 类似, 给出代码可运行演示。
<?php $if_none_match = ""; $headers = getallheaders(); while (list($header, $value) = each($headers)) { if ( "If-None-Match" == $header ) { $if_none_match = $value; break; } } if ( $if_none_match == "ead145f" ) { //告诉浏览器文档内容没有发生改变 header('HTTP/1.1 304 Not Modified'); exit(0); } else { header("ETag: ead145f"); } ?> <html> <head> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <style> </style> </head> <body> <h1>hello world!11</h1> <input type="text" value="test"/> <input type="button" value="button"/> <script type='text/javascript'> $("[type='button']").click(function(){ $("[type='text']").val("button click"); }) </script> </body> </html>
Expires 和 Max-age 支持浏览器离线缓存有效期定制,即不访问服务器
给出连个php头,可实验验证, 通过chrome浏览器前进后退访问, 无http请求, 仍然可显示页面,
但是URL地址栏回车键, 或者F5都会引起http重新请求。
header("Max-age: 86400");
header("Expires: Tue, 20 Mar 2015 04:00:25 GMT");