全部的缓存都是基于一套规则来帮助他们决定何时使用缓存中的副本提供服务(假设有副本可用的状况下,未被销毁回收或者未被删除修改)。这些规则有的在协议中有定义(如HTTP协议1.0和1.1),有的则是由缓存的管理员设置(如DBA、浏览器的用户、代理服务器管理员或者应用开发者)。php
对于浏览器端的缓存来说,这些规则是在HTTP协议头和HTML页面的Meta标签中定义的。他们分别从新鲜度和校验值两个维度来规定浏览器是否能够直接使用缓存中的副本,仍是须要去源服务器获取更新的版本。html
新鲜度(过时机制):也就是缓存副本有效期。一个缓存副本必须知足如下条件,浏览器会认为它是有效的,足够新的:浏览器
知足以上两个状况的一种,浏览器会直接从缓存中获取副本并渲染。缓存
校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它能够用来做为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过时,浏览器需求从新获取资源内容。安全
Web开发者能够在HTML页面的<head>节点中加入<meta>标签,代码以下:服务器
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">测试
上述代码的做用是告诉浏览器当前页面不被缓存,每次访问都须要去服务器拉取。使用上很简单,但只有部分浏览器能够支持,并且全部缓存代理服务器都不支持,由于代理不解析HTML内容自己加密
能够经过这个页面测试你的浏览器是否支持:Pragma No-Cache Test 。spa
一个URI的完整HTTP协议交互过程是由HTTP请求和HTTP响应组成的。有关HTTP详细内容可参考《Hypertext Transfer Protocol — HTTP/1.1》、《HTTP协议详解》等。firefox
Cache-Control与Expires的做用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据仍是从新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,若是同时设置的话,其优先级高于Expires。
配置Last-Modified/ETag的状况下,浏览器再次访问统一URI的资源,仍是会发送请求到服务器询问文件是否已经修改,若是没有,服务器会只发送一个304回给浏览器,告诉浏览器直接从本身本地的缓存取数据;若是修改过那就整个数据从新发给浏览器;
Cache-Control/Expires则不一样,若是检测到本地的缓存仍是有效的时间范围内,浏览器直接使用本地副本,不会发送任何请求。二者一块儿使用时,Cache-Control/Expires的优先级要高于Last-Modified/ETag。即当本地副本根据Cache-Control/Expires发现还在有效期内时,则不会再次发送请求去服务器询问修改时间(Last-Modified)或实体标识(Etag)了。
通常状况下,使用Cache-Control/Expires会配合Last-Modified/ETag一块儿使用,由于即便服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将可以很好利用304,从而减小响应开销。
你可能会以为使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为何还须要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的惟一标识符,可以更加准确的控制缓存。Last-Modified与ETag是能够一块儿使用的,服务器会优先验证ETag,一致的状况下,才会继续比对Last-Modified,最后才决定是否返回304。Etag的服务器生成规则和强弱Etag的相关内容能够参考,《互动百科-Etag》和《HTTP Header definition》,这里再也不深刻。
经过上表咱们能够看到,当用户在按F5进行刷新的时候,会忽略Expires/Cache-Control的设置,会再次发送请求去服务器请求,而Last-Modified/Etag仍是有效的,服务器会根据状况判断返回304仍是200;而当用户使用Ctrl+F5进行强制刷新的时候,只是全部的缓存机制都将失效,从新从服务器拉去资源。