304 Not Midified
该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304(服务器端资源未改变,可以直接使用客户端未过期的缓存)。304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3xx类别中,但是和重定向没有关系。
在进行条件请求时,客户端会提供给服务器一个带有If-Modified-Since,其值为服务器上次返回的Last-Modified响应头中的日期值,还会提供一个If-None-Match请求头,值为服务器上次返回的ETag响应头的值:
ETag和If-None-Match:这两个要一起说。Etag是上一次加载资源时,服务器返回的response header,是对该资源的一种唯一标识,只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器接受到If-None-Match的值后,会拿来跟该资源文件的Etag值做比较,如果相同,则表示资源文件没有发生改变,服务器就会返回HTTP/304 Not Modified响应,但没有响应体.客户端收到304响应后,就会从缓存中读取对应的资源,如果不相同,则表示资源发生了改变,那么服务器就会返回HTTP/200 OK响应,响应体就是该资源当前最新的内容.客户端收到200响应后,就会用新的响应体覆盖掉旧的缓存资源。
Last-Modified和If-Modified-Since:这两个也要一起说。Last-Modified是该资源文件最后一次更改时间,服务器会在response header里返回,同时浏览器会将这个值保存起来,在下一次发送请求时,放到request header里的If-Modified-Since里,服务器在接收到后也会做比对,如果相同则返回304,如果不同则返回200 ok。
为什么使用条件请求
当用户访问一个网页时,条件请求可以加速网页的打开时间(因为可以省去传输整个响应体的时间),但仍然会有网络延迟,因为浏览器还是得为每个资源生成一条条件请求,并且等到服务器返回HTTP/304响应,才能读取缓存来显示网页.更理想的情况是,服务器在响应上指定Cache-Control或Expires指令,这样客户端就能知道该资源的可用时间为多长,也就能跳过条件请求的步骤,直接使用缓存中的资源了.可是,即使服务器提供了这些信息,在下列情况下仍然需要使用条件请求:
- 在超过服务器指定的过期时间之后
- 如果用户执行了刷新操作的话
用户行为对浏览器缓存的控制
- 地址栏访问,链接跳转是正常用户行为,将会触发浏览器缓存机制;
- F5刷新,浏览器会设置max-age=0,跳过强缓存判断,会进行协商缓存判断;
- ctrl+F5刷新,跳过强缓存和协商缓存,直接从服务器拉取资源。