状态码
- 100-199:信息性状态码,通常和url协议相关,表示接收的请求正在处理
- 200-299:成功状态码,用于表示请求正常处理完毕
- 300-399:重定向状态码,表示要么有缓存,要么做了重定向用于跳转
- 400-499:客户端错误状态码,表示服务器无法处理请求
- 500-599:服务器错误状态码,表示服务器处理请求出错
其中比较常用的几个是:200,201,204,206,301,302,303,304,403,404,500,503
- 200 OK:表示从客户端发来的请求在服务器端被正常处理了,一切正常,对GET和POST请求的应答文档跟在后面。
- 201:服务器已经创建了文档,Location头给出了它的URL
- 204 No Content:请求处理成功但没有资源可返回
- 206 Partial Content:客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求
- 301 Moved Permanently:永久重定向,表示请求的资源已被分配了新的 URI,以后应使用资源现在所指的 URI
- 302 Found:临时重定向,表示资源仍然可以访问,这个重定向只是临时地从旧地址 A 跳转到地址 B
- 303 See Other:303 状态码和 302 Found 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法获取资源
当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送。
301、302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使用时大家都会这么做。
- 304 Not Modified:表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况(附带条件的请求是指采用 GET 方法的请求报文中包含 If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since 中任一首部),和重定向没有关系 。
- 403:资源不可用,服务器理解客户端的请求但拒绝处理,一般是权限问题
- 404:资源找不到
- 500:未知原因突然炸了
- 503:服务器过载炸了
http缓存控制
浏览器缓存控制分为强缓存和协商缓存,协商缓存必须配合强缓存使用。
首先浏览器第一次跟一个服务器请求一个资源,服务器在返回这个资源和response header的同时,会根据开发者要求或者浏览器默认,在response的header加上相关字段的http response header
浏览器在请求已经访问过的URL时,会判断是否使用缓存,判断是否使用缓存主要是判断缓存是否在有效期内。
- 当浏览器对某个资源的请求命中了强缓存时,利用[Expires]或者[Cache-Control]这两个http response header实现。
- [Expires]描述的是一个绝对时间,依据的是客户端的时间,用GMT格式的字符串表示,如Expires:Thu,31 Dec 2037 23:55:55 GMT,下次浏览器再次请求同一资源时,会先从客户端缓存中查找,找到这个资源后拿出它的[Expires]与当前时间做比较,如果请求时间在[Expires]规定的有效期内就能命中缓存,这样就不用再次到服务器上去缓存一遍,节省了资源。但正因为是绝对时间,如果客户端的时间被随意篡改,这个机制就实效了,所以我们需要[Cache-Control]
- [Cache-Control]描述的是一个相对时间,在进行缓存命中时都是利用浏览器时间判断。[Expires]和[Cache-Control]这两个header可以只启用一个,也可以同时启用,同时启用时[Cache-Control]优先级高于[Expires]
- 当浏览器对某个资源的请求没有命中强缓存(即缓存过期后),就会发起一个请求到服务器,验证协商缓存是否命中(即验证缓存是否有更新,虽然有效期过了,但我还能继续使用它吗?),如果命中则还是从客户端中加载。协商缓存利用的是[Last-Modified,If-Modified-Since]和[ETag,If-None-Match]这两对header来管理的
- [Last-Modified,If-Modified-Since]:原理和上面的[Expires]相同,服务器会响应一个Last-Modified字段,表示最近一次修改缓存的时间,当缓存过期后, 浏览器就会把这个时间放在If-Modified-Since去请求服务器,判断缓存是否有更新。区别是它是根据服务器时间返回的header来判断缓存是否存在,但有时候也会出现服务器上资源有变化但修改时间没有变化的情况,这种情况我们就需要[ETag,If-None-Match]
- [ETag,If-None-Match]:原理与上面相同,区别是浏览器向服务器请求一个资源,服务器在返回这个资源的同时,在response的header中加上一个Etag字段,这个字段是服务器根据当前请求的资源生成的唯一标识字符串,只有资源有变化这个串就会发生改动。当缓存过期后,浏览器会把这个字符串放在If-None-Match去请求服务器,比较字符串的值判断是否有更新,Etag的优先级比Last-Modified的更高, Etag的出现是为了解决一个缓存文件在短时间内被多次修改的问题,因为Last-Modified只能精确到秒。
- [ETag,If-None-Match]这么厉害我们为什么还需要[Last-Modified,If-Modified-Since]呢?有一个例子就是,分布式系统尽量关掉ETag,因为每台机器生成的ETag不一样,[Last-Modified,If-Modified-Since]和[ETag,If-None-Match]一般都是同时启用。
参考资料:
- 简述浏览器缓存是如何控制的评论区:马里奥,吴晗君。