你知道的304
服务器常见的状态码很多,特别是在原生Ajax(XMLHttpRequest)做响应判断的的时候不能只判断是否小于300。还应该加上等于304。今天来揭开304的神秘面纱~
304状态码: (Not Modified) 如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304状态码。简单的表达就是:服务端已经执行了GET,但文件未变化。
上面是百度百科的解释👆,我们可以理解为当我们第二次请求服务器的时候会根据缓存的相应条件进行对比,如果得出服务器的文件没有改变,那么就返回304状态码~
下面我们具体说说304缓存
304缓存分为强缓存与协商缓存
强缓存
我们第一次请求服务器后服务器返回的响应头内可能包含Cache-Control、Expires字段,这两个字段对应的就是强缓存👇
在HTTP1.0的时候只有Expires,它是一个绝对时间,代表着HTTP缓存的过期时间,因为服务器时间与本地可能存在不同,所以会影响到强缓存的命中。
所以在HTTP1.1的时候加入了Cache-Control,它是一个相对时间,常用的值为👇
值 | 说明 |
---|---|
public | 其他用户也可以使用缓存资源 |
private | 缓存服务器只给指定的用户返回缓存资源,对于其他用户不返回缓存资源 |
max-age | 告诉客户端,此资源在多久之内是未改变的,无需向服务器发送请求 |
s-maxage | 与max-age类似,只不过只能用于共享缓存 |
no-cache | 不直接使用缓存,需要向服务器发送请求 |
no-store | 所有内容不进行缓存 |
must-revalidate | 当前资源一定会向服务器发送请求,若请求失败会返回504网关超时 |
proxy-revalidate | 与must-revalidate类似,只不过只能使用共享缓存 |
当强缓存命中时,不需要与服务器进行通信,直接使用缓存资源
若未命中,则进行下一步协商缓存
协商缓存
当客户端第一次进行请求的时候响应头不但会包含Cache-Control、Expires这些强缓存字样,而且还会包含像Last-Modified或ETag
Last-Modified顾名思义,是上一次修改的时间。
当我们第二次发送请求的时候如果强缓存没有命中,向服务器发送的请求头中会携带If-Modified-Since字段,它的值为第一次服务器返回给我们的Last-Modified的值。如果这两个值相等说明该资源没有进行修改,则返回状态码304,否则返回状态码200,并将新资源发送给客户端。
而ETag是服务端的一个资源的标识,它代表着该资源的唯一性,每当该资源进行修改的时候,值都会做出相应的改变。同Last-Modified类似,第一次进行请求服务器的时候会返回ETag字段,当强缓存没有命中的时候,下一次请求会在请求头中携带If-None-Match字段,它的值与ETag的值一至,以此来判断该资源是否被修改,如果未被修改,返回状态码304,否则返回状态码200,并将新资源返回给客户端。
同样的在HTTP1.0的时候Last-Modified的值是一个绝对时间,会影响缓存命中,所以在HTTP1.1的时候提出了ETag。
缓存优先级
强缓存在前协商缓存在后
如果第一次请求资源时候,响应头返回的字段中既包含Cache-Control和Expires
强缓存中 Cache-Control > Expires
应头返回的字段中既包含ETag和Last-Modified
协商缓存中 ETag > Last-Modified