简单了解 HTTP 协议.

一、HTTP 请求流程

最初,HTTP 协议的出现主要是为了解决文本传输的难题,由于协议本身非常简单,于是在此基础上设想了很多应用方法并投入了实际使用。现在 HTTP 协议已经超出了 Web 这个框架的局限,被运用到了各种场景里。

目前主流的 HTTP 版本还是 HTTP/1.1。

HTTP 协议基于 TCP/IP 协议,会通过分层顺序与对方进行通信。首先作为发送端的客户端在应用层(HTTP 协议)发出一个想看某个 Web 页面的 HTTP 请求;接着,在传输层(TCP 协议)把从应用层处收到的数据(HTTP 请求报文)进行分割,并在各个报文上打上标记序号及端口号转发给网络层;然后,在网络层(IP 协议)增加作为通信目的地的 MAC 地址(ARP 协议)后转发给链路层;最后接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。

TCP 协议提供可靠的字节流服务,并且为了更容易传送大数据从而把数据分割,而且 TCP 协议能够确认数据最终是否送达到对方(三次握手)。

IP(Internet Protocol)协议的作用是把各种数据包传送给对方。

ARP 是一种用以解析地址的协议,根据通信方的 IP 地址就可以反查出对应的 MAC 地址。

DNS 提供域名到 IP 地址之间的解析服务。

二、HTTP 协议结构

1.请求报文

请求报文是由请求方法、请求 URI、协议版本、可选的请求首部字段和内容实体构成的。

keep-alive 表示只要客户端或服务端任意一端没有明确提出断开连接,则保持 TCP 连接状态。这样不会导致每次的请求造成无谓的 TCP 连接建立和断开,从而减少通信量的开销和服务端的负载,也能使页面的显示速度显著提高。

除了常见的 get/post 方法,HTTP/1.1 中还有诸多可使用的方法。

HTTP 方法 作用 说明
GET 获取资源 用来请求访问已被 URI 识别的资源
POST 传输实体主体 用来传输实体的主体
PUT 传输文件 自身不带验证机制,存在安全性问题
HEAD 获得报文首部 不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等
DELETE 删除文件 自身不带验证机制,存在安全性问题
OPTIONS 询问支持的方法 用来查询针对请求 URI 指定的资源支持的方法
TRACE 追踪路径 容易引发 XST(Cross-Site Tracing, 跨站追踪)攻击,不建议使用
CONNECT 用隧道协议连接代理 代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信

TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器端就将该数字减 1,当数值刚好减到 0 时, 就停止继续传输,最后接收到请求的服务器端则返回状态码 200 OK 的响应。

CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输给代理服务器。

2.响应报文

响应报文基本上由协议版本、状态码(表示请求成功或失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成。

响应状态码的类别:

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

常见的响应状态码含义:

状态码 含义 描述
200 OK 请求正常处理并响应
204 No Content 请求正常处理,但在返回的响应报文中不含实体的主体部分,客户端不做更新
206 Partial Content 客户端进行范围请求,响应报文中由 Content-Range 指定范围的实体内容
301 Moved Permanently 永久性重定向,响应报文中的 Location 首部字段会带回新的 URL 地址
302 Found 临时性重定向,希望用户(本次)能使用新的 URI 访问
303 See Other 临时性重定向,与 302 类似,但 303 状态码明确表示客户端应当采用 GET 方法获取资源
304 Not Modified 服务端判定资源没有改变,不响应资源,客户端可以从本地缓存中获取资源
400 Bad Request 客户端请求报文中存在语法错误
401 Unauthorized 客户端请求需要 HTTP 认证信息
403 Forbidden 客户端请求资源的访问被服务器拒绝了,多见于权限问题
404 Not Found 服务器无法找到请求的资源
500 Internal Server Error 服务端执行请求时发生了错误
502 Bad Gateway 错误网关,服务器作为网关或代理,从上游服务器收到了无效的响应
503 Service Unavailable 服务端暂时处于超负载或正在进行停机维护,现在无法处理请求
504 Gateway Time-out 服务器作为网关或代理,未及时从上游服务器接收请求

tips:当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送。

三、HTTP 状态管理

HTTP 是一种不保存状态,即无状态(stateless)协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。也就是说,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,以及减少服务器 CPU 和内存资源的损耗,从而特意把 HTTP 协议设计成如此简单的。

那么 HTTP 协议怎么管理状态呢?这就要说到 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。

Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。

服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

四、其他

1、HTTP 内容编码是指在不丢失实体信息的前提下所进行的压缩,内容编码后的实体由客户端接收并负责解码。常见的内容编码有以下几种:

  • gzip(GUN zip)
  • compress(UNIX 系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

2、HTTP 分块传输编码(Chunked Transfer Coding)会将实体主体分成多个部分(块)。每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“0(CR+LF)”来标记,分块传输编码的实体主体由客户端接收并负责解码。

3、HTTP 发送的一份报文主体中可含有多类型实体,通常是在图片或文本文件等上传时使用,多类型实体的每个部分类型中,都可以含有首部字段,多类型实体包含的对象如下:

  • multipart/form-data,在 web 表单文件上传时使用。
  • multipart/byteranges,状态码 206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用。
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="field1"
Joe Blow
--AaB03x
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
...(file1.txt的数据) ...
--AaB03x

HTTP 协议的 header 中的 Range 是用来指定资源的 byte 范围,比如:“Range:bytes=5001-10000” 表示请求 5001- 10000 字节的资源。针对范围请求,响应会返回状态码为 206 Partial Content 的响应报文,并在 header 字段指明 “ContentType:multipart/byteranges”

4、Comet 是一种高级的 Ajax 技术,通过延迟应答,模拟实现服务器端向客户端推送(Server Push)的功能。通常,服务器端接收到请求,在处理完毕后就会立即返回响应,但为了实现推送功能,Comet 会先将响应置于挂起状态,当服务器端有内容更新时,再返回该响应。因此,服务器端一旦有更新,就可以立即反馈给客户端。

内容上虽然可以做到实时更新,但为了保留响应,一次连接的持续时间也变长了。期间,为了维持连接会消耗更多的资源。另外,Comet 也仍未解决 HTTP 协议本身存在的问题。

5、HTTP 协议的缺点?

  • 一条连接上只可发送一个请求。
  • 请求只能从客户端开始。客户端不可以接收除响应以外的指令。
  • 请求/响应首部未经压缩就发送。首部信息越多延迟越大。
  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多。
  • 可任意选择数据压缩格式。非强制压缩发送。
posted @ 2020-05-20 11:13  JMCui  阅读(446)  评论(0编辑  收藏  举报