前言
本文将介绍HTTP缓存机制中的强缓存与协商缓存,将从命中机制,响应与请求头三个方面对比
命中机制
浏览器第一次请求时,就会产生缓存
浏览器后续在进行请求请求相同网页时,就会判断命中哪个缓存
响应
强缓存
浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK
状态码为200分为 200 form memory cache 和 200 from disk cache
200 form memory cache:不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。
200 from disk cache:不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。
优先访问memory cache,其次是disk cache
协商缓存
向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;
请求头
命中什么缓存,就是通过请求头来判断的
强缓存
- Expires: response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存
- Cache-Control:
- max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;
- s-maxage:和max-age是一样的,不过它只针对代理服务器缓存而言;
- public:指示响应可被任何缓存区缓存;
- private:只能针对个人用户,而不能被代理服务器缓存;
- no-cache:强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到 请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。这个很容易让人产生误解,使人误 以为是响应不被缓存。实际上Cache-Control: no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性
- no-store:禁止一切缓存(这个才是响应不被缓存的意思)。
cache-control是http1.1的头字段,expires是http1.0的头字段,如果expires和cache-control同时存在,cache-control会覆盖expires,建议两个都写。
协商缓存
Last-Modifed/If-Modified-Since 和 Etag/If-None-Match是分别成对出现的,呈一一对应关系
Last-Modifed/If-Modified-Since:
- Last-Modifed: 浏览器向服务器发送资源最后的修改时间
- If-Modified-Since: 当资源过期时(浏览器判断Cache-Control标识的max-age过期),发现响应头具有Last-Modified声明,则再次向服务器请求时带上头if-modified-since,表示请求时间。服务器收到请求后发现有if-modified-since则与被请求资源的最后修改时间进行对比(Last-Modified),若最后修改时间较新(大),说明资源又被改过,则返回最新资源,HTTP 200 OK;若最后修改时间较旧(小),说明资源无新修改,响应HTTP 304 走缓存。
Etag/If-None-Match:
- Etap: web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定
- If-None-Match: 当资源过期时,浏览器发现响应头里有Etag,则再次像服务器请求时带上请求头if-none-match(值是Etag的值)。服务器收到请求进行比对,决定返回200或304
Q.E.D.