浏览器缓存有两种方式:1.强缓存 2.协商缓存
主要过程是:浏览器请求资源的时候,先检查资源是否命中强缓存,如果命中就从缓存中加载。如果没有(或者资源过期),就检查是否命中协商缓存,如果命中,就还是从缓存中加载。再没有就从服务器上加载啦。
(这样莫名的像cache命中。。一级cache缺失就检查二级cache。并且每级的缺失都会导致性能的消耗)
1.强缓存
方法:在header处设置cache-control或者expires来规定资源过期的时间(前者优先级较高)。这样浏览器接受到资源之后就会缓存下资源。下次请求资源时,检查资源是否过期。
优点:本地缓存,减少每次的http请求时间(浏览器默认缓存图片和css,js等静态资源)
缺点:如果服务器端的资源已经变化了,但是本地的缓存却还没过期,那么就不能及时获得更新的资源了
2.协商缓存
方法:利用【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】进行标识。
服务器进行response时设置last-modified表示资源上次修改时间,浏览器请求时附上if-modified-since,是记录的资源上次修改的时间。如果一致,就从缓存中加载。
由于可能存在服务器时间和电脑时间不一致的情况,用etag唯一标志一种版本的资源,If-None-Match是上次请求资源时接受的etag。服务器返回资源时发送etag,浏览器请求资源时用if-none-match检查是否一致。但是不管是否一致,浏览器都会返回最新的etag
优点:能及时更新资源。缩小资源获取时间。
缺点:增加http请求。分布式环境etag可能各个地方不一样。并需要保持last-modified一致。需要配合强缓存才有意义。
tip:ctl+f5是直接从服务器加载,跳过两种缓存
f5是跳过强缓存
*************************************************************
之前电面的时候回答错了,而且也不详细,难怪人家不要我QUQ。下次绝!对!不会再被拒了!
说一下两种缓存的使用环境,之前有些懵懵的。
浏览器第一次访问一个地址的时候,会把静态文件(不知道有没有动态)缓存到本地,会带有expire,etag,last-modify这样的参数。
然后第二次请求该文件的时候,检查缓存文件是否过期,如果没有过期就使用缓存,这个时候返回的是200(from cache)。如果过期了,就发送请求给服务器,服务器查看last-modify或者etag,看文件是否更新过了,如果没有更新过,就返回304,这时候浏览器就再从缓存中取文件。如果更新过了,自然就是返回新的文件。
浏览器是否缓存一个文件,主要看response的请求头,当然服务器的请求头是建议浏览器缓存或者不缓存,浏览器不一定会这么做。
request和response中都有缓存相关的字段,主要有cache-control, pragma, etag, modified等等。
1.request
在request中发送cache-control告诉服务器客户端处理缓存的方式:
no-cache -- 告诉服务器不使用缓存,要重新取文件
max-age -- 缓存过期时间
only-if-cache -- 在有缓存的情况下只用缓存
也可以用pragma做缓存判断,可以取no-cache,为了兼容HTTP1.0。但是如果有cache-control,会被cache-control覆盖。
还需要判断文件的更新情况。
if-match / if-none-match会把etag传递给服务器,然后服务器匹配两方的etag。(对应etag)
或者用if-modified-since,把缓存中文件上次修改的时间传给服务器,服务器查看本地文件的上次修改时间是否一样(对应modified字段)
2.response
response中的cache-control:
no-cache -- 告诉客户端不要缓存文件
max-age -- 缓存过期时间
only-if-cache -- 在有缓存的情况下只用缓存
private/public -- private告诉浏览器只缓存一个文件,public让缓存可以被多个用户共享
自然也有etag和modified,last-modified,expires。
参考资料:
https://www.shiyanlou.com/questions/3044