HXWfromDJTU/blog

网络篇 - 从报文分析 http 状态码

HXWfromDJTU opened this issue · 0 comments

HTTP状态码 - 从报文头一一分析

1XX

100 Continue

行为表现

HTTP/1.1 协议里设计 100 (Continue) HTTP 状态码的的目的是,在客户端发送 Request Message 之前,HTTP/1.1 协议允许客户端先判定服务器是否愿意接受客户端发来的消息主体(基于 Request Headers)。

设计含义

  1. clientserverpost (较大)数据之前,允许双方“握手”,如果匹配上了,Client 才开始发送(较大)数据。
  2. 如果客户端直接发送请求数据,但是服务器又将该请求拒绝的话,这种行为将带来很大的资源开销。

操作

如果 client 预期等待“100-continue”的应答,那么它发的请求必须包含一个 " Expect: 100-continue" 的头域!

客户端 Request Header

服务端处理

101 Switching Protocols

表示访问当前资源需要更换协议进行数据传输,比如 Websocket 握手连接。

2XX

2xx 一类的状态码,表示你的请求已经被服务器正确地处理了,没有遇到其他问题,服务器选择性地返回一些内容

200 OK

请求被服务器成功处理,服务器会根据不同的请求方式返回结果

201 Created

请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随Location 头信息返回。

204 NO CONTENT

  1. 服务器已经完成了处理,但是不需要返回响应体
  2. 200 状态下,没有实体返回的区别在于,浏览器处理 204 的状态码,只是回去读取报文头的更新信息
  3. UA 是一个浏览器,请求的时候是<a href="xxx">标签形式,204 则不会发生页面跳转,相对应 200 下则会发生跳转。

RFC的描述原文

206 Partial Content

  1. 这个状态码的出现,表示客户端发起了范围请求,而服务器只成功处理了其中的一部分
  2. 此时的客户端请求,必须包含有range字段,而服务端的报文中,必须包含由,Content-Range指定的实体内容(entity)

Range字段含义

  1. XXX--rrr 有头有尾,表示使用多线程下载。
  2. �XXX-- 有头无尾,表示断点续传,在线播放
  3. ---XXX 有尾无头,表明只要最后的XXXbytes
  4. XXX--ccc,yyy-uuu,qqq-zzz 表示明确范围的多范围下载

增强校验

  1. 使用If-ModifiedIf-Match这两套去保证分段的资源是可靠的,资源在分段过程中没有被修改
    • 浏览器通过发送请求对象的 ETag 或者自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。
  2. 或者是用�If-Range去请求,总是跟 Range 头部一起使用。
    If-Range浏览器告诉 WEB 服务器
    • 如果我请求的对象没有改变,就把我缺少的部分给我
    • 如果对象改变了,就把整个对象给我。

范围请求详细过程请参考这篇文章👉

3XX

表示服务器端已经接受到了请求,必须对请求进行一些特殊的处理之后,才能够顺利完成此处请求

301 MOVE PERMANELTLY

请求的资源已经被永久地重定向了,301 状态码的出现表示请求的URL对应的资源已经被分配了新的定位符。

  1. HEAD请求下,必须在头部Location字段中明确指出新的URI
  2. 除了有Location字段以外,还需要在相应体中,附上新的 URI 的链接文本
  3. 若是客户使用 POST 请求的话,服务端若是使用重定向,则需要经过客户的同意
  4. 对于 301 来说,资源除非额外指定,否则默认都是可缓存的。

使用场景

我们使用http访问一些只接受 https �资源的时候,浏览器设置了自动重定向到 https,那么首次访问就会返回 301 的状态码。

302 FOUND

  1. 301状态码意思几乎一样,不同点在于302是临时的重定向,并只对本次的请求进行重定向
  2. 若用户将本 URI 收藏了起来,不去修改书签中的指向。
  3. 重定向的时候,RFC 规范规定,不会去改变请求的方式。但实际上,很多现存的浏览器都直接将 302 响应等同于 303 响应,并且在重定向的时候,使用 GET 方式返回报文中Location字段指明的URL
  4. 对于资源缓存,只有在 Cache-ControlExpires 中进行了指定的情况下,这个响应才是可缓存的。

使用场景

我们使用的网站短地址,访问的时候就会临时重定向到我们压缩前地址指向的页面。

303 SEE OTHER (http 1.1)

  1. 表明用户请求的资源,还存在另一个对应的 URI,其实也是重定向的含义
  2. 大多数浏览器会将 303 状态码同样处理为 302,而且是直接将非 GETHEAD请求改为 GET 请求。
  3. 重定向的时候,统一使用 GET 形式去进行

307 Temporary Redirect (http1.1)

  1. HTTP1.1 文档中 307 状态码则相当于 HTTP1.0 文档中的 302 状态码
  2. 当客户端的POST请求收到服务端307状态码响应时,需要跟用户询问是否应该在新URI上发起POST方法,也就是说,307是不会把POST转为GET的。
  3. 也就是说 307的处理,应该完全遵守http1.0时代对302处理。

总结重定向类型 3XX

  1. http1.0和http 1.1都规定,若客户端发送的是非 GET 或者 HEAD 请求,响应头中携带 301302 的时候,浏览器不会自动进行重定向,而需要询问用户,因为此时请求的情况 很可能 已经发生变化。

    http 1.1 301说明

    http 1.0 302说明

    http 1.1 302说明

    但是实际上,所有的浏览器都会默认把 POST 请求直接改为 GET 请求。

  2. �对于301状态码,搜索引擎在抓取新内容的同时,也将旧网址替换为重定向后的网址。而对于302状态码则会保留旧的网页内容。

  3. 兼容性:服务端考虑准备使用303的时候,一般还是会使用302代替,因为要兼容许多不支持http 1.1的浏览器,而对与要进行 307 返回的时候,浏览器一般会将要重定向的 URL 放到 response.body 中,让用户去进行下一步操作。

  4. 303307的存在,就是细化了http 1.0中302的行为,归根结底是由于 POST(等对服务器有伤害的请求)方法的非幂等属性引起的。

http 1.1 303说明

http 1.1 307说明

304 Not Modified(差点漏了你)

  1. 表示本次请求命中了缓存策略,客户端应该直接从本地的缓存中取出内容。
  2. 304 状态码返回时,不包含任何响应的主题部分

4XX

400 BAD REQUEST

  1. 表示该请求报文中存在语法错误,导致服务器无法理解该请求。客户端需要修改请求的内容后再次发送请求。

  2. 一般也可以用于用户提交的表单内容不完全正确,服务端也可以用 400 来响应客户端

    跨域OPTION请求中的 400

401 UNAUTHORIZED

  1. 该状态码表示发送的请求需要有通过HTTP认证
  2. 当客户端再次请求该资源的时候,需要在请求头中的Authorization包含认证信息。

验证失败返回 401

客户端主动提供 Authorization 信息

www-authenticate:Basic表示一种简单的,有效的用户身份认证技术。

Basic 验证过程简述

  1. 客户端访问一个受 http 基本认证保护的资源。
  2. 服务器返回 401 状态,要求客户端提供用户名和密码进行认证。(验证失败的时候,响应头会加上WWW-Authenticate: Basic realm="请求域"。)
    401 Unauthorized     
    WWW-Authenticate: Basic realm="WallyWorld"
    
  3. 客户端将输入的用户名密码用Base64进行编码后,采用非加密的明文方式传送给服务器。
    Authorization: Basic xxxxxxxxxx.
    
  4. 服务器将 Authorization 头中的用户名密码解码并取出,进行验证,如果认证成功,则返回相应的资源。如果认证失败,则仍返回401状态,要求重新进行认证。

403 FORBIDDEN

  1. 该状态码表明对请求资源的访问被服务器拒绝了。
  2. 服务器没有必要给出拒绝的详细理由,但如果想做说明的话,可以在实体的主体部分原因进行描述 。
  3. 未获得文件系统的访问权限,访问权限出现某些问题,从未授权的发送源IP地址试图访问等情况都可能发生403响应。

404 NOT FOUND

  1. 表明无法找到制定的资源
  2. 通常也被服务端用户表示不想透露的请求失败原因

405 Method Not Allowed

表示该资源不支持该形式的请求方式,在Response Header中返回 Allow 字段,携带支持的请求方式

412 Precondition Failed

在请求报文中的If-xxx字段发送到服务端后,服务端发现没有匹配上。比如,If-Match:asfdfsdzxc,希望匹配ETag值。

417 Exception Failed

我们先来看看RFC是怎么定义的...

在请求头Expect中指定的预期内容无法被服务器满足,或者这个服务器是一个代理服务器,它有明显的证据证明在当前路由的下一个节点上,Expect 的内容无法被满足。

5XX

500 Internal Server Error

表示服务器端在处理客户端请求的时候,服务器内部发生了错误

502 Bad Gateway

一般表示连接服务器的便捷路由器出问题了,导致请求不能到达。我们最常见的应该是这个页面

然后资源请求的时候,详细的报文

![](https://raw.githubusercontent.com/HXWfromDJTU/blog/master/blog_assets/502.png)  

解决办法

  1. 前端开发尝试 Ctrl + F5 进行强制刷新,多次从服务器重新拉取数据,排除是网关服务器偶尔波动引起的
  2. 找到开发人员,查看一下对应服务器日志,排查问题 与 进行重启操作

503 Service Unavaliable

  1. 该状态码表示服务器已经处于一个超负荷的一个状态,或者是所提供的服务暂时不能够正常使用

  2. 若服务器端能够事先得知服务恢复时间的话,可以在返回503状态码的同时,把恢复时间写入Retry-After字段中
    常见的页面形式

    报文解读

  3. 注意,要是503的报文返回时,没有携带Retry-After�的报文头,那么客户端应将次返回处理为500

参考文章

[1] 100 continue 的秘密
[2] http状态码 -百度百科
[3] 301与302
[4] websocket探秘
[5] 200/204/206-302/303/307 -cnblog
[6] HTTP状态码302、303和307的故事
[7] RFC- HTTP1.1
[8] 206断续下载
[9] 断点续传-http协议里Header参数Range