重要的 HTTP 协议,很重要。《图解 HTTP》第一、二、三、四、六章读书笔记,作者:上野 宣,译者:于均良。其余章节笔记在HTTP 协议(下)

了解 Web 和网络基础

使用 HTTP 协议访问 Web

Web 使用 HTTP(HyperText Transfer Protocol)协议作为规范,完成从客户端到服务端等一系列运作流程,建立通信。

网络基础 TCP/IP

1、 TCP/IP 协议族

计算机与网络设备要相互通信,双方就得基于相同的方法。

协议中存在格式各样的内容。从电缆的规格到 IP 地址的选定方法、寻找异地用户的方法、双方建立通信的顺序,以及 Web 页面显示需要处理的步骤。

这些互联网相关协议的集合总称为 TCP/IP。

2、 TCP/IP 分层管理

TCP/IP 协议族按层次分为 4 层: 应用层、传输层、网络层、数据链路层。

分层的好处是当有改动时不用牵一发而动全身,只需把变动的层替换掉即可;分层后每个层的内部设置也更自由、简单。

TCP/IP 协议族各层的作用:

  1. 应用层 决定了提供服务时的通信活动。TCP/IP 协议族预存了各类通用的应用服务。比如:FTP 和 DNS。HTTP 协议也在这层。
  2. 传输层 为应用层提供位于网络连接两端的数据传输。有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Data Protocol,用户数据包协议)。
  3. 网络层 用来处理网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(传输路线)到达对方计算机,并把数据包传送给对方。网络层的作用就是选择一条传输路线,使得通信顺利进行。
  4. 链路层 用来处理连接网络的硬件部分。硬件上的范畴均在链路层的作用范围之内。

3、 TCP/IP 通信传输流

利用 TCP/IP 协议族进行网络通信是,发送端从应用层往下走,接收端往应用层上走。

以 HTTP 为例,发送端在应用层(HTTP 协议)发出一个想看某个 Web 页面的 HTTP 请求。

接着,为了传输方便,在传输层(TCP 协议)把从应用层收到的数据(HTTP 请求报文)进行分割。并在各个报文上打上标记序号及端口号后转发给网络层。

在网络层(IP 协议),增加通信目的地的 MAC 地址,转发给链路层。

接收端在链路层接收到数据,按序往上层发送,直到应用层,才算真正接收到客户端发送过来的 HTTP 请求。

在发送端,每经过一层就会被打上该层所属的首部信息,反之,接收端每经过一层会把对应的首部消去。这种把数据信息包装起来的做法称为封装(encapsulate)。

与 HTTP 关系密切的协议 DNS、TCP 和 IP

1、 负责域名解析的 DNS 服务

DNS服务和 HTTP 协议一样位于应用层,它提供域名到 IP 地址之间的解析服务,或逆向从 IP 地址反查域名的服务。

2、 确保可靠性的 TCP 协议

TCP位于传输层,提供可靠的字节流服务。

字节流服务是指将大块数据分割成以报文段为单位的数据包进行管理。

TCP 协议采用三次握手(three-way handshaking)策略确保数据无误。握手过程使用 TCP 的标志——SYN(synchronize)和 ACK(acknowledgement)。

发送端发送一个带 SYN 标志的数据包给对方,接收端收到后,回传一个带有 SYN/ACK 标志的数据包以示确认信息,最后,发送端再回传一个带 ACK 标志的数据,代表“握手”结束。

只要是在网络上跑的包,都是完整的。对 TCP 协议来说,三次握手也好,重试也好,只要想发出去包,就要有 IP 层和 MAC 层,不然是发不出去的。

3、 负责传输的 IP 协议

IP(Internet Protocol)网际协议位于网络层。TCP/IP 协议族中的 IP 指的就网际协议。IP 和 IP 地址是两个术语,IP 是一种协议的名称。

IP 协议的作用是把各种数据包传送给对方。两个重要的条件是 IP 地址和 MAC 地址(Media Access Control Address)。IP 地址指明了节点被分配到的地址,MAC 地址是指网关所属的固定地址。IP 地址可以和 MAC 地址进行配对。IP 地址可变换,MAC 地址基本不变。

IP 间的通信依赖 MAC 地址,在网络上,通常是经过多台计算机和网络设备中转才能连接到对方。中转中会利用下一站中转设备的 MAC 地址来搜索中转目标。这时,会采用 ARP 协议(Address Resolution Protocol),一种解析地址的协议,通过通信方的 IP 地址反查出对应的 MAC 地址。这种机制称为路由选择。

4、 各种协议与 HTTP 协议的关系

URI 和 URL

URI(Uniform Resource Identifier),由某个协议方案表示的资源的定位标识符。URL 表示资源的地点(互联网上所处的位置),URL 是 URI 的子集。

简单的 HTTP 协议

HTTP/1.1 版本。

HTTP 协议用于客户端和服务端之间的通信

通过请求和响应的交换达成通信

HTTP 协议规定,请求从客户端发出,服务端响应该请求并返回。

  1. 请求报文
  2. 响应报文

HTTP 是不保证状态的协议

HTTP 协议不对请求和响应之间的通信状态进行保存。

请求 URI 定位资源

客户端发送请求时,需要将 URI 作为请求报文中的请求 URI。

告知服务意图的 HTTP 方法

  1. GET 获取资源
  2. POST 传输实体主体
  3. PUT 传输文件
  4. HEAD 获取报文首部,和 GET 方法一样,只是不返回报文主体,用于确认 URI 的有效性及资源的更新日期等
  5. DELETE 删除文件
  6. OPTIONS 询问支持的方法
  7. PATCH 局部更新

持久连接节省通信量

HTTP 协议的初始版本,每进行一次 HTTP 通行就要断开一次 TCP 连接。

持久连接是建立 1 次 TCP 连接后进行多次请求和响应,注意,这里的多次请求,是等上一次请求的响应回来后,才能再发送下一个请求,容易造成“对头堵塞”的问题(HTTP/2 可以解决),在 HTTP/1.x 中,客户端想发起多个并行请求,必须使用多个 TCP 连接,大多数浏览器限制每个主机最多打开 6 个连接。在 HTTP/1.1 中,所有的连接默认都是持久连接。

持久连接带来的另外一个好处就是并发请求,以前发生请求后需等待并接收响应才能发下一个。持久连接使得多数请求以管线化的方式发送。

上面提到了 TCP 三次握手建立连接,下面来说一说 TCP 四次挥手释放连接:

数据传输结束后,通信双方都可以释放连接。A 的应用进行先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接,报文首部 FIN 标志,进入 FIN-WAIT-1 状态,B 收到报文后发出确认 ACK,进入 CLOSE-WAIT 状态,此时 TCP 连接处于半关闭状态,即 A 已经没有数据要发送了,但 B 若发生数据,A 仍要接收。A 收到 B 的确认后进入 FIN-WAIT-2 状态,若 B 已经没有要发送的数据了,就通知 TCP 释放连接,B 发送释放报文 FIN,A 收到 B 的释放报文后,必须发出确认 ACK 报文。现在 TCP 连接还没有释放,必须经过时间等待计时器设置的时间 2MSL 后,A 才进入 CLOSED 状态。MSL 叫做最长报文段寿命,RFC793 建议设为 2 分钟。从 A 进入 TIME-WAIT 状态后,要经过 4 分钟才能进入 CLOSED 状态,才能开始建立下一个新的连接。

Cookie 可根据服务器的响应报文内的Set-Cookie首部字段信息,通知客户端保存 Cookie。当下次客户端在往该服务器发送请求时,会自动在请求报文中加入 Cookie 值。服务器收到客户端发来的 Cookie 就可得到之前的状态。

HTTP 报文内的 HTTP 信息

HTTP 报文

用 HTTP 协议交互的信息被称为 HTTP 报文。分请求和响应报文。由报文首部和报文主体组成,两者用空行(CR+LF)划分。

请求报文和响应报文的结构

编码提升传输速率

1、 压缩传输的内容编码

内容编码后的实体由客户端接收并解码。常见的内容编码有:

  1. gzip
  2. compress
  3. deflate
  4. identity(不编码)

2、 分割发送的分块传输编码

Transfer-Encoding: chunked

分块传输编码会将实体主体分成多个部分。每个块用十六进制来标记块的大小,实体的最后一个块会使用“0”来标记。

获取部分内容的范围请求 Range

针对范围请求,响应会返回状态码 206 Partial Content。

内容协商返回最合适的内容

内容协商机制是指客户端和服务端就响应的资源内容进行交涉,然后提供给客户端最为合适的资源。比如包含在请求报文中的一些首部:

  1. Accept
  2. Accept-Charset
  3. Accept-Encoding
  4. Accept-Language
  5. Content-Language

HTTP 首部

在客户端与服务端之间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。

  1. 通用首部
  2. 请求首部
  3. 响应首部
  4. 实体首部

通用首部字段

请求报文和响应报文都会使用的首部

  1. Cache-Control 控制缓存的行为
  2. Connection 管理持久连接
  3. Date 创建 HTTP 报文的日期和时间
  4. Pragma 和 Cache-Control 功能一样,兼容之前的版本
  5. Transfer-Encoding 规定了传输报文主体时采用的编码方式
  6. Upgrade 用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信。

请求首部字段

  1. Accept 通知服务端客户端能够处理的媒体类型以及相对优先级
  2. Accept-Charset 支持的字符集以及优先级
  3. Accept-Encoding 支持的内容编码以及优先级
  4. Accept-Language 能够处理的自然语言集

q表示权重值,用分号(;)分割,范围 0~1(可精确到小数点后 3 位)。默认权重为 q=1.0

  1. Authorization 告知服务端,客户端的认证信息
  2. Proxy-Authorization 接收到代理服务器发来的认证质询时,告知代理服务器认证需要的信息
  3. Host 告知服务器,请求的资源所处的互联网主机名和端口号。 为虚拟主机的兴起打下了基础单台服务器分配多个域名的虚拟主机,相同 IP 地址下运行着多个域名,通过 Host 字段明确指出请求的主机名。
  4. If-Match 告知服务器匹配资源的实体标记(ETag)值,一致,执行请求,反之,返回 412 Precondition Failed。
  5. If-None-Match 该字段值的实体标记与请求资源的 ETag 不一致时,处理该请求。
  6. If-Modified-Since 告知服务器返回某个时间之后更新的资源,如果请求的资源没有更新,返回 304 Not Modified。
  7. If-Unmodified-Since 请求的资源只有在字段值指定的日期之后没有更新的情况下,才能处理。
  8. If-Range 告知服务器字段值(ETag 或时间)和请求资源的 ETag 或时间一致时,与 Range 结合,处理范围请求。反之,返回全体资源。
  9. Range 获取部分资源,返回 206 Partial Content。无法处理时,返回全部资源
  10. Referer 发出请求的页面所在的域。
  11. User-Agent 将浏览器和用户代理名称的信息告知服务器

响应首部字段

  1. Accept-Ranges 告知客户端能否处理范围请求
  2. Age 源服务器在多久前创建了响应
  3. ETag 告知客户端实体标识
  4. Location 配合 3xx: Redirection 响应,提供重定向 URI
  5. Retry-After 告知客户端应该在多久之后再次发送请求。主要配合 503 Service Unavailable,或者 3xx Redirect。
  6. Server 告知客户端当前服务器上安装的 HTTP 服务应用程序的信息。
  7. Vary 源服务器向代理服务器传达关于使用本地缓存方法的命令
  8. Proxy-Authenticate 把代理服务器要求的认证信息发送给客户端
  9. WWW-Authenticate 告知客户端用于访问请求 URI 指定资源的认证方案,401 Unauthorized 中。

实体首部字段

  1. Allow 通知客户端能够支持 Request-URI 的 HTTP 方法,405 Method Not Allowed 响应返回
  2. Content-Encoding 告知客户端实体主体内容的编码方式
  3. Content-Language 告知客户端,实体主体使用的自然语言
  4. Content-Length 实体主体的大小,单位字节。使用内容编码后,不能使用 Content-Language 字段
  5. Content-Type 实体主体的媒体类型
  6. Content-Location 报文主体对应的 URI
  7. Content-MD5 检查报文主体在传输过程中是否完整
  8. Content-Range 针对范围请求,告知客户端返回的是实体的哪部分范围请求
  9. Expires 将资源失效的日期告知客户端
  10. Last-Modified 资源最后修改的时间
  1. Set-Cookie
属性 说明
NAME=VALUE Cookie 的名称和值
expires=DATE Cookie 的有效期
path=PAHT 限定 Cookie 发送范围的文件目录
domain=域名 Cookie 适用的域名
Secure 仅在 HTTPS 通信时才会发送 Cookie
HttpOnly Cookie 不能被 JavaScript 脚本访问
  1. Cookie 当客户端想获得 HTTP 状态管理支持时, 就会在请求中包含从服务器接收到的 Cookie。

内容编码后:

内容没编码:

重定向 302:

其他首部字段

  1. X-Frame-Options 属于响应首部,用于控制网站内容在其他网站的 Frame 标签的显示
  2. X-XSS-Protection 属于响应首部,用于控制浏览器 XSS 防护机制的开关
  3. DNT 请求首部,Do Not Track,控制是否允许追踪
  4. P3P 响应首部,可以让 Web 网站上的个人隐私变成一种仅供程序可理解的形式, 以达到保护用户隐私的目的

HTTP 状态码

状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。以 3 位数字和原因短语组成。

类别 原因短语
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错

2XX 成功

  1. 200 OK 表示客户端发来的请求在服务器端被正常处理了
  2. 204 No Content 表示服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。
  3. 206 Partial Content 表示客户端进行了范围请求,

3XX 重定向

  1. 301 Moved Permanently 永久重定向。表示请求的资源已经被分配了新的 URI,以后应使用新的 URI,如果之前的 URI 已经保存为书签,应按 Location 首部字段提示的 URI 重新保存。
  2. 302 Found 临时性重定向。表示请求的资源已被分配了新的 URI,希望用户(本次)使用新的 URI。不会改变书签。
  3. 303 See Ohter 和 302 有着相同的功能,但是 303 明确客户端应当采用 GET 方法获取资源。
  4. 304 Not Modified 表示客户端发送附带条件的请求(If-Modified-Since)时,服务器允许访问资源,但未满足条件的情况。

4XX 客户端错误

  1. 400 Bad Request 表示请求报文中存在语法错误
  2. 401 Unauthorized 表示请求需要 HTTP 认证的认证信息,若之前已经进行过 1 次请求,则表示用户认证失败
  3. 403 Forbidden 表示请求资源的访问被服务器拒绝了,如,访问权限有问题
  4. 404 Not Found 表示服务器上无法找到请求的资源
  5. 405 Menthod Not Allowed 表示请求的方法不允许使用,如,服务器值实现了 PATCH 局部更新资源,并没有实现 PUT 替换资源,而请求使用了 PUT
  6. 407 Proxy Authentication Required 表示需要同代理服务器进行认证
  7. 409 Conflict 由于冲突,请求无法被完成。
  8. 412 Precondition Failed 请求的资源不符合请求头中的 IF-*的某些条件
  9. 416 Request Range Not Satisfialbe 请求区间无效

5XX

  1. 500 Internal Server Error 表示服务器在执行请求时发生了错误,也可能是 Web 应用存在 bug 或故障
  2. 502 Bad Gateway Web 服务器作为网关或代理服务器时收到了无效影响。比如:我们向服务器 A 请求下载葫芦娃,但 A 其实只是一个代理服务器,需向 B 请求葫芦娃,但是不知道为啥 B 不理他或者给他错误
  3. 503 Service Unavailable 表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求
  4. 504 Gateway Timeout 网关访问超时。B 不理 A,超时了。

参考文献

  1. (总结)HTTP 常见错误返回代码