简单了解 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 协议的缺点?
- 一条连接上只可发送一个请求。
- 请求只能从客户端开始。客户端不可以接收除响应以外的指令。
- 请求/响应首部未经压缩就发送。首部信息越多延迟越大。
- 发送冗长的首部。每次互相发送相同的首部造成的浪费较多。
- 可任意选择数据压缩格式。非强制压缩发送。