读书笔记3 —— HTTP 状态码详解

HTTP状态码

100 ~ 199 —— 信息性状态码

状态码 原因短语 含义
100 Continue 说明收到了请求的初始部分,请客户端继续。发送了这个状态码之后,服务器在收到请求之后必须进行响应
101 Switching Protocols 说明服务器正在根据客户端的指定,将协议切换成 Update 首部所列的协议

100 Continue

首先,客户端先发送了一个请求,这个请求的header中包含了一个属性expect: 100-continue。这种情况一般出现于上传大容量body或者是需要验证的时候。这时服务器会读取请求的header,如果服务器可以提供这项服务的话则会返回一个100 continue的响应。客户端再将http请求发送回去。然后服务器会读取请求的body并且在成功后返回200状态码。

101

暂时未找到相关具体介绍,自己也没有实际应用场景

200 ~ 299 —— 成功状态码

状态码 原因短语 含义
200 OK 请求没问题,实体的主体部分包含了所请求的资源
201 Created 用于创建服务器对象的请求(比如,PUT)。响应的实体主体部分中应该包含各种引用了已创建的资源的URL,Location首部包含的则是最具体的引用。服务器必须在发送这个状态码之前创建好对象
202 Accepted 请求已被接受,但服务器还未对其执行任何动作。
203 Non-Authoritative Information 不常见
204 No Content 响应报文包含首部和状态行,没有实体的主体部分
205 Reset Content 负责告知浏览器清除当前页面中的所有HTML表单元素
206 Partical Content 成功执行了一个部分或Range请求

300 ~ 399 —— 重定向状态码

重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源,要么就提供一个替代的响应而不是资源的内容。如果资源已被移走,可发送一个重定向状态码和一个可选的Location首部来告知客户端资源已被移走,以及现在可以在哪里找到它。

HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0
Date: Fri, 01 Mar 2019 00:46:26 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 81
Location: https://www.smartisan.com <- 这里指定了浏览器需要跳转的地址
Connection: keep-alive

Redirecting to <a href="https://www.smartisan.com">https://www.smartisan.com</a>.

可以通过某些重定向状态码对资源的应用程序本地副本与源端服务器上的资源进行验证。比如,HTTP应用程序可以查看其资源的本地副本是否仍然是最新的,或者在源端服务器上资源是否被修改过。例如客户端可以发送一个特殊的If-Modified-Since首部携带着本地资源副本的修改日期,如果服务端的资源在此日期之后没有改动,则可以返回304状态码,而不是文档内容。

状态码 原因短语 含义
300 Multiple Choices 客户端请求一个实际上指向多个资源的URL时会返回这个状态码,比如服务器上有某个HTML文档的英语和中文版本。返回这个代码时会带有一个可选项列表,这样用户就可以选择他希望使用的那一项了。
301 Moved Permanently 在请求的URL已被永久移除时使用。响应的Location首部中应该包含资源现在所处的URL
302 Found 与301状态码类似,但是是临时定位资源。意味着例如从a跳转到b,如果是301的话,浏览器下次再访问a时,会直接跳转到b,不会再向a发送请求。如果是302的话,则还是会请求a,然后根据响应决定执行什么
303 See Other 告知客户端应该使用另一个URL来获取资源。新的URL位于响应报文的Location首部。
304 Not Modified 客户端可以通过所包含的请求首部,使其请求变成有条件的。如果客户端发起了一个条件GET请求,而最近的资源未被修改的话,就可以通过用这个状态码来说明资源未被修改。带有这个状态码的响应不应该包含实体的主体部分。
305 Use Proxy 必须通过一个代理来访问资源。Location 域中将给出指定的代理所在的 URI 信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能建立305响应。
306 未被使用
307 Temporary Redirect 与302状态码类似

302、303、307的渊源

上面表格可能看得人一头雾水,这三个状态码之间到底有什么区别?下面给出了两个超链接,是HTTP协议的文档说明,摘抄对这三个状态码的描述来搞清楚这个事情。
HTTP/1.0 3xx 文档
HTTP/1.1 3xx 文档

HTTP/1.0 时代

302 - Moved Temporarily
The requested resource resides temporarily under a different URL.
Since the redirection may be altered on occasion, the client should
continue to use the Request-URI for future requests.

...

If the 302 status code is received in response to a request using
the POST method, the user agent must not automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.

    Note: When automatically redirecting a POST request after
    receiving a 302 status code, some existing user agents will
    erroneously change it into a GET request.

简单翻译一下302是干嘛的,如果一个资源临时不存在,可以返回一个302,并在首部的Location里面指定需要跳转的地址。但是,如果客户端发送的是POST请求,浏览器一定不能自动转发请求,必须要用户手动确认才行。

这里问题来了,目前的浏览器一般是怎么处理这种情况的,一般浏览器收到302后,直接会对Location中的地址发送GET请求(仿佛大家像商量好一般都不去按照文档实现)。

注意:HTTP/1.0时代结束了,那时候没有303307

HTTP/1.1 时代

302 - Found (这里原因短语有升级哦)
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
      to change the method on the redirected request.  However, most
      existing user agent implementations treat 302 as if it were a 303
      response, performing a GET on the Location field-value regardless
      of the original request method. The status codes 303 and 307 have
      been added for servers that wish to make unambiguously clear which
      kind of reaction is expected of the client.

这里的302和以前的302其实骨子里是一样的,就是更新了一个原因短语而已。但是Note里面的话很有意思,说的是,现在绝大部分浏览器对待302303一样(别着急,下面就介绍303是什么样的),根本不去管原始请求的请求方法是什么,一律GET请求进行跳转。这句话和上面我们所说的一样,浏览器厂商们都不约而同的不去遵守302的文档。这样的后果导致302基本是废的,因为你如果POST请求返回了302,可能就会有多种情况了(虽然大部分都是直接用GET请求跳转走),所以程序员们需要一个真正的不管什么请求都统一用GET跳转走的状态码还有一个绝对不能自动转成GET跳转走的状态码,而不能像302这样会有模棱两可的行为出现,我觉得聪明的你已经猜到了结局。没错,303307应运而生。

303 - See Other
The response to the request can be found under a different URI and
SHOULD be retrieved using a GET method on that resource. 

摘抄一句话足矣,浏览器使用GET方法来处理返回的URL

307 - Temporary Redirect
If the 307 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.

307悲剧的又说了一遍以前的302

两句话总结,HTTP协议规范定义了302,浏览器厂商们没有完全遵守它(浏览器们的实现方式是未来的303),导致只能新增一个303来和浏览器的行为相匹配。然后302已经被玩坏了,那就只好再创建一个307重新声明一下以前的302,这次浏览器们有303用了,总该遵守307的规则了吧。

400 ~ 499 —— 客户端错误状态码

有时客户端会发送一些服务器无法处理的东西,比如格式错误的请求报文,或者最常见的是,请求一个不存在的 URL。
浏览网页时,我们都看到过臭名昭著的 404 Not Found 错误码——这只是服务器在告诉我们,它对我们请求的资源一无所知。

状态码 原因短语 含义
400 Bad Request 用于告知客户端它发送了一个错误的请求
401 Unauthorized 与适当的首部一同返回,在这些首部中请求客户端在获取对资源的访问权之前,对自己进行认证。
402 Payment Required 现在这个状态码还未使用,但已经被保留,以作未来之用
403 Forbidden 用于说明请求被服务器拒绝了。如果服务器想说明为什么拒绝请求,可以包含实体的主体部分来对原因进行描述。如果服务端不想告诉客户端为啥被拒绝,可以使用404
404 Not Found 用于说明服务器无法找到所请求的URL。通常会包含一个实体,以便客户端应用程序显示给用户看
405 Method Not Allowed 发起的请求中带有所请求的URL不支持的方法时,使用此状态码。应该在响应中包含Allow首部,以告知客户端对所请求的资源可以使用哪些方法
406 Not Acceptable 客户端可以指定参数来说明它们愿意接收什么类型的实体。服务器没有与客户端可接受的URL相匹配的资源时,使用此代码。通常,服务器会包含一些首部,以便客户端弄清楚为什么请求无法满足
407 Proxy AuthenticationRequired 与401状态码类似,但用于要求对资源进行认证的代理服务器
408 Request Timeout 如果客户端完成请求所花的时间太长(不同服务器可以配置不同的超时时长),服务器可以回送此状态码,并关闭连接
409 Conflict 用于说明请求可能在资源上引发的一些冲突。服务器担心请求会引发冲突时,可以发送此状态码。响应中应该包含描述冲突的主体
410 Gone 与404类似,只是服务器曾经拥有过此资源。主要用于Web站点的维护,这样服务器的管理者就可以在资源被移除的情况下通知客户端了
411 Length Required 服务器要求在请求报文中包含Content-Length首部时使用
412 Precondition Failed 客户端发起了条件请求,且其中一个条件失败了的时候使用。客户端包含了Expect首部时发起的就是条件请求
413 Request Entity TooLarge 客户端发送的实体主体部分比服务器能够或者希望处理的要大时,使用此状态码
414 Request URI Too Long 客户端所发请求中的请求URL比服务器能够或者希望处理的要长时,使用此状态码
415 Unsupported MediaType 服务器无法理解或无法支持客户端所发实体的内容类型时,使用此状态码
416 Requested Range NotSatisfiable 请求报文所请求的是指定资源的某个范围,而此范围无效或无法满足时,使用此状态码
417 Expectation Failed 请求的Expect请求首部包含了一个期望,但服务器无法满足此期望时,使用此状态码。

500~599 —— 服务器错误状态码

有时客户端发送了一条有效请求,服务器自身却出错了。这可能是客户端碰上了服务器的缺陷,或者服务器上的子元素,比如某个网关资源,出了错

状态码 原因短语 含义
500 Internal Server Error 服务器遇到一个妨碍它为请求提供服务的错误时,使用此状态码
501 Not Implemented 客户端发起的请求超出服务器的能力范围(比如,使用了服务器不支持的请求方法)时,使用此状态码
502 Bad Gateway 作为代理或网关使用的服务器从请求响应链的下一条链路上收到了一条伪响应(比如,它无法连接到其父网关)时,使用此状态码
503 Service Unavailable 用来说明服务器现在无法为请求提供服务,但将来可以。如果服务器知道什么时候资源会变为可用的,可以在响应中包含一个Retry-After首部
504 Gateway Timeout 与状态码408类似,只是这里的响应来自一个网关或代理,它们在等待另一服务器对其请求进行响应时超时了
505 HTTP Version NotSupported 服务器收到的请求使用了它无法或不愿支持的协议版本时,使用此状态码。有些服务器应用程序会选择不支持协议的早期版本

猜你喜欢

转载自blog.csdn.net/weixin_42461410/article/details/88012641