面经复习-浏览器缓存和304

参考链接1
参考链接2

文章仅复习记录用。

一、浏览器缓存

浏览器第一次打开一个网页获取资源后,根据返回的header信息来告诉如何缓存资源。

  • 浏览器第一次请求时:

面经复习-浏览器缓存和304
面经复习-浏览器缓存和304

  • 浏览器后续请求时:

面经复习-浏览器缓存和304
面经复习-浏览器缓存和304

第二次请求服务器返回了一个304。

在第一次请求服务器的时候在获取资源之后是会先把该资源缓存在本地的,同时服务器response返回了一个响应头ETag,ETag全称Entity Tag,用来标识一个资源。在具体的实现中,ETag可以是资源的hash值,也可以是一个内部维护的版本号。但不管怎样,ETag应该能反映出资源内容的变化,这是Http缓存可以正常工作的基础。服务器对于hello world这个字符串使用上述返回的ETag来表示,只要hello world这个资源不变,这个Etag就不会变。

客户端第二次请求服务器的时候,利用请求头If-None-Match来告诉服务器自己已经有个ETag为xxx的资源。如果服务器上的资源没有变化,也就是说服务器上的资源的ETag也是xxx的话,服务器就不会再返回该资源的内容,而是返回一个304的响应,告诉浏览器该资源没有变化,缓存有效,浏览器将直接调用本地缓存。

  • 浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息),若命中直接从缓存中获取资源信息,包括缓存header信息,本次请求就不会与服务器进行通信。

  • 如果没有命中强缓存,浏览器会发送请求到服务器,请求会携带第一次返回的有关缓存的header字段信息(Last-Modifued/If-Modified-Since和Etag/If-None-Match),由服务器根据header信息来比对结果是否协商缓存命中。若命中,则服务器返回新的响应header信息更新缓存中的对应header信息,但是不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容。

二、强缓存相关header字段

浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。

Expires策略

Expires是Web服务器响应消息头字段在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
Expires设置失效时间,精确到时分秒。 不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。

Cache-control策略(重点关注)

Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。

http协议头Cache-Control :
值可以是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age

Public指示响应可被任何缓存区缓存。
Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
no-cache指示请求或响应消息不能缓存
no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

三、协商缓存相关header字段

Last-Modifued/If-Modified-SinceEtag/If-None-Match这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modifued或者Etag),则后续请求会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modifued或者Etag字段,则请求头也不会有对应字段

Last-Modifined/If-Modified-Since
Last-Modified/If-Modified-Since要配合Cache-Control使用。

  • Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
  • 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
也要配合Cache-Control使用

  • Etag:服务器响应时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。

  • If-None-Match:当资源过期时,浏览器发现响应头里有Etag,则再次像服务器请求时带上请求头if-none-match(值是Etag的值)。服务器收到请求进行比对,决定返回200或304

为什么既有Last-Modified还有Etag(两者为什么并存,有什么好处)

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
  • 某些服务器不能精确的得到文件的最后修改时间。
  • 这时,利用Etag能够更加准确的控制缓存,因为Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符。
  • Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

四、用户行为对缓存的影响

面经复习-浏览器缓存和304

五、cookie和浏览器缓存的区别

当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie会帮你在网站上所打的文字或是一些选择都纪录下来。当下次你再光临同一个网站,WEB 服务器会先看看有没有它上次留下的 Cookie资料,有的话,就会依据 Cookie里的内容来判断使用者,送出特定的网页内容给你。

具体来说cookie机制采用的是在客户端保持状态的方案(保存客户浏览器请求服务器页面的请求信息),而session机制采用的是在服务器端保持状态的方案。
Cookie存储的数据量受限制,大多数的浏览器为4K因此不要存放大数据。由于并非所有的浏览器都支持Cookie,数据将以明文的形式保存在客户端。
Cookie是用来保存就是被人盗取也无关紧要的信息,例如用户的喜好、用户搜索过的关键字等,用户信息、id字段不建议保存在Cookie中,因为别人可以分析存放在本地的Cookie进行Cookie欺骗。

Cache用于在Http请求期间保存页面或者数据,主要用来保存大容量信息,如数据库中的多个表。即使应用程序终止,只要Cache方法中定义的缓存时间未过期,下次开启应用程序时,缓存的数据依然存在。
Cache是应用程序级的,主要用来缓存计算或查询结果,减轻服务器负担,并加快响应速度。它允许将频繁访问的服务器资源存储在内存中,当用户发出相同的请求后,服务器不是再次处理而是将Cache中保存的数据直接返回给用户。可以看出Cache节省的是时间—服务器处理时间。

面经复习-浏览器缓存和304