浏览器缓存(Browser Caching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览。
只要浏览器不关闭缓存,且请求的是图片或文件,在response里设置了ETag后,下次请求同一资源时,一定可以在request的META中看到HTTP_IF_NONE_MATCH。
相关说明:
示例代码:
HTML
浏览器缓存主要有两类:缓存协商:Last-midified ,Etag 和彻底缓存:cache-control,Expires。[1]
1、ETag/HTTP_IF_NONE_MATCH
ETag相当于请求资源的“指纹”,服务器端设置,浏览器端返回HTTP_IF_NONE_MATCH,ETag值没有在http中明确要求,只要是双引号引起来就可以。
示例代码:
Django:
def img(request):
tag = request.REQUEST["tag"]
image = open('/root/workspace/'+tag+'.png', 'rb')
data=image.read()
image.close()
response=HttpResponse(content=data,content_type="image/png")
response["ETag"] = "999"
return response
HTML:
<div>
<img src="/img">
</div>
只要浏览器不关闭缓存,且请求的是图片或文件,在response里设置了ETag后,下次请求同一资源时,一定可以在request的META中看到HTTP_IF_NONE_MATCH。
2、Cache-Control
ETag方式需要程序员自己处理,比如根据值的判断返回304或直接无视仍返回资源(200),也就是不管怎么着,浏览器的请求还是会到达服务器端的,而Cache-Control则可以通过一定的设置来杜绝这种情况。
Cache-Control的设置如下所示。
public | 所有内容都将被缓存 |
private | 内容只缓存到私有缓存中 |
no-cache | 所有内容都不会被缓存 |
no-store | 所有内容都不会被缓存到缓存或 Internet 临时文件中 |
must-revalidation/proxy-revalidation | 如果缓存的内容失效,请求必须发送到服务器/代理以进行重新验证 |
max-age=xxx (xxx is numeric) | 缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用, 并如果和Last-Modified一起使用时, 优先级较高 |
打开一个新的浏览器窗口 | 在原窗口中单击 Enter 按钮 | 刷新 | 单击 Back 按钮 | |
---|---|---|---|---|
public | 浏览器呈现来自缓存的页面 | 浏览器呈现来自缓存的页面 | 浏览器重新发送请求到服务器 | 浏览器呈现来自缓存的页面 |
private | 浏览器重新发送请求到服务器 | 第一次,浏览器重新发送请求到服务器;此后,浏览器呈现来自缓存的页面 | 浏览器重新发送请求到服务器 | 浏览器呈现来自缓存的页面 |
no-cache/no-store | 浏览器重新发送请求到服务器 | 浏览器重新发送请求到服务器 | 浏览器重新发送请求到服务器 | 浏览器重新发送请求到服务器 |
must-revalidation/proxy-revalidation | 浏览器重新发送请求到服务器 | 第一次,浏览器重新发送请求到服务器;此后,浏览器呈现来自缓存的页面 | 浏览器重新发送请求到服务器 | 浏览器呈现来自缓存的页面 |
max-age=xxx (xxx is numeric) | 在 xxx 秒后,浏览器重新发送请求到服务器 | 在 xxx 秒后,浏览器重新发送请求到服务器 | 浏览器重新发送请求到服务器 | 在 xxx 秒后,浏览器重新发送请求到服务器 |
Django:
def img(request):
tag = request.REQUEST["tag"]
image = open('/root/workspace/'+tag+'.png', 'rb')
data=image.read()
image.close()
response=HttpResponse(content=data,content_type="image/png")
response["Cache-Control"] = "max-age=3600"
return response
HTML代码1:
<div>
<img src="/img">
</div>
像这种情况,max-age=3600只有在新窗口打开该页面或通过enter来刷新该页面时才有效果,如果时F5的话,服务器端收到的cache-control是max-age=0,可以通过下面这个代码来更好的说明问题
window.setInterval(function(){
$.ajax({
url:"/img",
success: function(data){},
error: function(){}
});
},2000);
这样的话服务器只会在第一次接到请求,此后的1h浏览器都不会再向浏览器发送请求了,不管你是不是停留在当前页面,也就是说即使你关掉了浏览器,30min后打开它还是不会去请求,更极端的情况,程序员自己把html页面改了,比如改成了
<img src="/img">
再刷新页面,只要每到1h,还是不会去请求,前提是请求链接还是/img。
还有一种情况,见下面代码:
Django
def img(request):
tag = request.REQUEST["tag"]
image = open('/root/workspace/'+tag+'.png', 'rb')
data=image.read()
image.close()
response=HttpResponse(content=data,content_type="image/png")
response["Cache-Control"] = "max-age=3600"
return response
HTML
<html>
<body>
<head>
<script src="/static/jquery.min.js"></script>
<script type="text/javascript">
var tag = 0;
var load = function(){
tag = 1-tag;
$.ajax({
url:"/img",
data:{
"tag": tag
},
success: function(data){
},
error: function(){}
});
};
</script>
</head>
<div>
<button οnclick="javascript:load()">click</button>
</div>
</body>
</html>
在同一个页面,每次请求的资源不一样,但不刷新,那这个max-age还是有效的。
另,虽然来自缓存,但其返回的代码仍可能是200
关于其他方式的使用,可参考:http://blog.csdn.net/liveinjs/article/details/34151451