violet0sea / note

can not open gist, so write here
0 stars 0 forks source link

浏览器缓存相关 #6

Open violet0sea opened 7 years ago

violet0sea commented 7 years ago

浏览器为什么要缓存? 其实不缓存也是可以的,只不过每次都需要向服务器发送请求,服务器处理请求后返回相关资源。这个过程没有什么异常;但是,这一切的行为都是有代价的,客户端与服务器之间通信,服务器处理相应,返回资源后的资源下载都是耗时的,毕竟时间就是金钱,此外,这些过程会产生流量,造成没必要的浪费。如果可以通过一些列的措施减少上述的问题,那么对于用户都是很好的体验。

浏览器缓存所使用的请求字段: Expires、Cahce-Control、Last-Modified、ETag(服务端相应头字段);

服务器在返回响应时,会携带http报头,用于描述响应的相关信息(内容类型、长度、缓存)。

请求该网址返回的信息

Response-Header: alt-svc:quic=":443"; ma=2592000; v="39,38,37,35" cache-control:must_revalidate, public, max-age=3600 content-encoding:gzip content-language:zh-cn content-length:21350 content-type:text/html; charset=utf-8 date:Thu, 31 Aug 2017 02:10:57 GMT expires:Thu, 31 Aug 2017 03:10:57 GMT last-modified:Fri, 02 Jun 2017 14:17:36 GMT server:Google Frontend status:200 strict-transport-security:max-age=31536000; includeSubdomains vary:Accept-Encoding vary:Accept-Language x-cloud-trace-context:630923c682a94172c94baa51ba39af6f x-content-type-options:nosniff x-frame-options:SAMEORIGIN x-xss-protection:1; mode=block

Request-Header: :authority:developers.google.com :method:GET :path:/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=zh-cn :scheme:https accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 accept-encoding:gzip, deflate, br accept-language:zh-CN,zh;q=0.8,zh-TW;q=0.6,fr;q=0.4 cache-control:max-age=0 cookie:devsite_dark_code=off; NID=111=vR4Ltxb4D7fU5Ytnp2ahDhm7D4Mjr_YkLKcz_HnlvJuYgKqjv3krX49teTdOl-G7euqOBWtpe902rf3a9RP342q5u0_u54Pua8Qf5MsS7TLMR_U1573jb7uysJe78eO4; _ga=GA1.3.2134379993.1504145083; _gid=GA1.3.744730594.1504145083; _gat_tracker0=1; _gat_tracker1=1 if-modified-since:Fri, 02 Jun 2017 14:17:36 GMT referer:https://www.google.com/ upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36 x-chrome-uma-enabled:1 x-client-data:CJC2yQEIorbJAQjBtskBCPqcygEIqZ3KAQjSncoBCNyeygEIlKLKAQ==

cache-control: no-cache:表示必须先于服务器确认返回的相应是否发生了变化,这里需要结合ETag来验证资源是否改变; no-store:禁止浏览器以及所有中间缓存存储相应,每次请求都会返回获取服务器上最新的资源; public:不仅允许用户缓存,还允许缓存服务器缓存; private:只允许单个用户缓存;

上面的服务器返回一个内容长度为21350字节的响应,指示客户端将其缓存3600S(max-age),可以被任何对象缓存(public),缓存过期时需要校验(must-revalidate),expires(http1.0版本中有效)指定Thu, 31 Aug 2017 03:10:57 GMT日期后,资源过期,因为上面设置了cache-control(http1.1版本),所以这个字段会被忽略,expires 的缺点:客户端的时间与服务器的时间相差很大,会造成误差,基于这个原因,在http1.1版本适用cache-control代替,max-age设置的是相对时间

此外,还有ETag是资源的特定版本的标识符,可以使缓存更加高效,比较etag能够快速确定资源是否变化。第一次请求服务器返回一个ETag标识,浏览器几下这个表示,再次请求资源时,客户端会携带一个If-None-Match,携带这个标识的请求头,服务端会对这个标识做比较,匹配返回304,否则返回新的资源+200;当同时存在etaghelast-Modified时,etag优先级会高一些;负载均衡的机器每一台服务器生成的etag都会不一样,这里需要注意。 Last-Modified&If-Modified-Since 浏览器第一次请求一个地址时,响应头会携带一个Last-Modified:Fri, 02 Jun 2017 14:17:36 GMT的标记,表示资源在服务器上最后被修改的时间;接下来刷新浏览器,浏览器会发送一个携带if-modified-since:Fri, 02 Jun 2017 14:17:36 GMT表示的请求,服务器通过比较改时间来判断资源是否更新,更新需要发送新的资源,否则返回一个304。这两个字段在一些请求和相应中没有设置,服务器如果采取了负载均衡策略,需要保证每台机器的last-modified必须一致,否则会导致前后的请求发送到不同的机器上导致比对失败。