一、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 | 服务端执行请求时发生了错误 |
503 | Service Unavailable | 服务端暂时处于超负载或正在进行停机维护,现在无法处理请求 |
tips:当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送。
三、HTTP 状态管理
HTTP 是一种不保存状态,即无状态(stateless)协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。也就是说,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,以及减少服务器 CPU 和内存资源的损耗,从而特意把 HTTP 协议设计成如此简单的。
那么 HTTP 协议怎么管理状态呢?这就要说到 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。