前言
面试被问到了,但是记忆不清晰。在此做个笔记
http 状态码
304是一种http的状态码,只有当出现了协商缓存且缓存有效的时候才会出现。
协商缓存与强缓存
前提:当浏览器第一次请求文件时,服务器会给文件打上标识(Expires/Cache-Control),同时也会携带etag/last-modified。
强缓存:当浏览器下一次请求相同的文件时,浏览器会查询xxx(可能时本地缓存系统),查到当前文件的上一次的response headers存在Expires/Cache-Control其中之一的属性,然后判断是否过期,如果没有过期就直接使用缓存数据,network上显示的状态码是200 dist cache/200 momory cache。 整个过程叫做强缓存。
协商缓存:当强缓存没命中成功时,会向服务器发送if-none-match/if-modified-since 值(放在请求头),这个值是上一次请求返回回来的。 服务器接收到值后,会判断文件是否有修改,如果没有,那么就直接返回304 not modified(无内容),然后浏览器会直接使用缓存,并更新文件对应的Expires/Cache-Control值;假如文件出现了修改,那么服务器会返回200状态码,还有新的文件内容。
总结
请求先命中强缓存,不过期就是200,直接使用缓存;过期就命中协商缓存,如果文件没有修改,服务器返回304,使用缓存;如果服务器的文件有修改,则返回200。
Expires/Cache-Control利弊
Expires: 是一个绝对的GMT时间。当服务器的时间跟客户端的时间不一致时,会无法命中强缓存。 Cache-Control: max-age是一个相对的时间戳,不会出现Expires的问题,所以才会取代Expires。 其次 no-cache(直接走协商缓存)、no-store(禁止缓存,无法协商)、public(允许中间代理+客户端都可以缓存)、private(禁止中间代理缓存,允许客户端缓存)多种形式的缓存可以更容易满足开发者的需求。
etag/last-modified 利弊
etag: 是算法根据文件内容得出的hash值。 last-modified:是文件最后的修改时间(只能精确到s)。
- 对于频繁修改的文件来说,文件需要更精确的时间,而last-modified只能精确到s。所以可能会存在文件不一致的问题。
- 一些文件周期性改变的文件内容并没有改变,只是时间改变了,会导致last-modified不走协商缓存。
- 部分服务器不支持精确时间。
- etag 比较重,因为是对内容的一个hash,所以很重。
最后附上草稿一张