HTTP缓存,换句话说就是,服务器告诉浏览器,你可以缓存我输出的内容,下次再访问相同内容时,就不用向我拿数据了。而浏览器则是个乖小孩。根据HTTP响应,将获取的内容存储到自己指定的文件夹目录下。下次有人再访问相同URL时。先去查找自己目录下是否有这个URL的内容,有没有过期。有这个URL内容且没有过期。直接输出的页面。
HTTP缓存主要有两中方式:
1. 对比缓存
对比缓存,虽然浏览器缓存了服务器输出的内容,但浏览器和服务器都是很谨慎的人。
服务器跟浏览器说,你虽然缓存了我内容,当然这些内容不会时时变化,但以防万一,我给你这份内容的一个标识(ETAG,Last-Modified),每次有人访问相同内容(URL)的时候,你先拿这个ETAG/If-Modified-Since给我,让我比对一下看内容有没有被修改过。如果有修改过,我给你份新内容,你重新缓存,没有被修改的话,我返回一个状态码304给你,你就直接用你缓存的。最后,服务器还跟浏览器说。我给你内容可能是有过期时间的哦,你也要检查过期时间。定期向我拿最新的数据
优点:
因为每次访问,浏览器会去询问服务器是否内容被修改过。保持输出的内容都是最新的,具有实时性。同时服务器只是通过ETAG这个标志,去判断内容是否被更新过。所以服务器不用每次都经历一个完整的数据查询和处理过程。同时在内容没有变化时候,只返回一个状态码304,没有其他内容 ,报文大小和请求时间大大减少
缺点:
就是每次都需要去访问服务器。都需要一个来回。
2.强制缓存
在强制缓存中,服务器是一个梁山好汉,比较简单直接,不喜欢麻烦。它告诉浏览器。你直接缓存给你内容。这份内容有个有效期。在这份内容没有过期之前。就不用向我要数据了,直接用你缓存的。
而浏览器也省的麻烦。每次有人访问这个内容的时候,就看看内容有没有过期,如果没有,直接输出,如果过期了,就向服务器要一份新的重新缓存
优点:
省去了每次有人访问这份内容时,都要去询问服务器这份内容的是否为最新的这个过程,就是省宽带
缺点:
无法保证内容的实时性,可能访问到是过期的内容
注:在同时存在对比缓存和强制缓存时。浏览器也懒,优先使用强制缓存
HTTP缓存相关字段:
Expires: http1.0使用,告诉浏览器缓存的到期时间。但存在一个问题,服务器,和浏览器所在的电脑时间可能不一致,这个到期时间就存在问题了。
Cache-Control(http1.1使用),规则如下:
private: 客户端可以缓存
public: 客户端和代理服务器都可缓存(前端的同学,可以认为public和private是一样的)
max-age=xxx: 缓存的内容将在 xxx 秒后失效
no-cache: 需要使用对比缓存来验证缓存数据
no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发
Last-Modified: 服务器在响应请求时,告诉浏览器内容的最后修改时间
If-Modified-Since:
浏览器再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的内容最后修改时间。服务器收到请求后发现有头If-Modified-Since 则与被请求内容的最后修改时间进行比对。若内容的最后修改时间大于If-Modified-Since,说明内容又被改动过,则响应整片内容,返回状态码200;
若内容的最后修改时间小于或等于If-Modified-Since,说明内容无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
If-None-Match:
浏览器再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。服务器收到请求后发现有头If-None-Match 则与被请求内容的唯一标识进行比对,不同,说明内容又被改动过,则响应整片内容内容,返回状态码200;相同,说明内容无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
Etag:服务器响应请求时,告诉浏览器当前内容在服务器的唯一标识(生成规则由服务器决定)。 优先级高于(Last-Modified/If-Modified-Since/If-None-Match)