问题
- 最近代理一个源服务器,在源服务器返回的基础上加一些业务,其中一个html(该页面需要在GET请求url不变情况下,根据服务器时间定制document.ready脚本)
- 后面几次请求html内容没有变化,且在devtool上要么没有发送请求,要么返回200或304
- 查阅一番资料,原来是浏览器的缓存机制
缓存
https://datatracker.ietf.org/doc/html/rfc7232
https://datatracker.ietf.org/doc/html/rfc7234
- 浏览器缓存控制指有条件筛选那些请求真正发向服务端,那些请求使用本地缓存,可以减少带宽,提高通信效率
- 浏览器缓存控制包括缓存是否开启,开启时校验是否失效
- 浏览器缓存控制非常适合GET请求那些不会动态改变或频繁改变的资源
- 浏览器缓存控制是通过请求响应的头部信息字段实现的(headers)
缓存控制开关
- Pragma:HTTP/1.0中规定,
no-cache
未指定缓存控制 - Cache-Control:http1.1定义,优先级高于Pargma,请求和响应中都可以包含,指令用于缓存开关和简单的有效时间
- Expires:响应头字段,当Cache-Control设置了max-age时Expires被忽略,GMT时间戳
- 打开新窗体,地址栏回车等的缓存行为可能不一样
缓存验证
-
max-age和Expires只是简单的验证缓存有效期,可以通过第一次请求request的响应response 200 headers有更细节的先决条件验证
-
ETag:资源的特定版本的标识符,指定版本比指定时间更容易判断,能快速确定此资源是否变化(不仅用于缓存控制,还配合Range If-Range实现请求部分响应)
-
If-Match:请求字段头,服务器在请求的资源满足列出的ETag值时才会返回资源(If-None-Match与之含义相反)
-
If-Unmodified-Since:请求字段头,服务器在请求的资源满足列出的日期时间之后对内容进行过修改的情况下才会将资源返回;如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的304响应(返回304意味着服务端告诉客户端(浏览器),服务端无需再次传输请求的内容,客户端可以缓存中从之前返回内容)(If-Unmodified-Since与之含义相反)
-
If-Match优先级比If-Unmodified-Since高
-
Last-Modified:服务器最后一次修改资源的时间戳(Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT),精确度比ETag要低,这是一个备用机制
demo
- 第一次请求,服务端返回200时,在headers加入TEag
- 之后请求,浏览器将TEag加入到If-None-Match加入到headers
- 服务端根据之前的TEag与最新TEag比较,一样返回304,否则重新返回200+最新TEag
<!--statuecode.html-->
<html>
<head>
<title>
状态码http response status code
</title>
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
</head>
<body>
<div>
<table>