HTTP用于客户端和服务端之间的通信
HTTP,全称超文本传输协议,是应用层协议,用于客户端和服务端之间的通信。请求文本或图片等资源的一端称为客户端,提供文本或图片等资源的一端称为服务端。
报文
客户端和服务端通过报文进行通信,HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。
由客户端发送请求报文,服务端接收到请求报文,分析后对请求做出响应,并返回响应报文。
请求报文和响应报文的结构
请求报文由请求行(包含用于请求的方法,请求URI 和HTTP 版本)、可选的请求首部字段和报文主体构成。
响应报文由状态行(包含协议版本,请求成功或失败的数字状态码,用以解释状态码的原因短语)、可选的响应首部字段以及报文主体构成
实体的概念
实体作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。HTTP 的报文主体用于传输请求或响应的实体主体。
一张图理解实体与报文的关系
请求 URI 定位资源
HTTP 协议使用 URI 定位互联网上的资源。
统一资源名称(URN)表示资源的名称
统一资源定位符(URL)表示资源的位置
URN和URL是统一资源标识符(URI)的两种形式,都可以标识一个资源。
常见的指定 URI 的方式有:
- 完整的URL
- 相对首部字段 HOST的 URL
*
(用于对服务器本身发起请求,而不针对具体的资源,比如 OPTIONS 方法)
HTTP方法
方法 | 说明 |
---|---|
GET | 获取URI指定的资源 |
POST | 使用服务端管理的标识创建资源;向指定资源提交数据,请求服务器处理,更新部分资源 |
PUT | 将封闭实体的资源存储在请求的URI之下:资源标识由客户端指定,资源不存在则创建,存在则更新 |
DELETE | 删除指定资源 |
HEAD | HEAD 方法和GET 方法一样,只是不返回报文主体部分。用于确认URI 的有效性及资源更新的日期时间等 |
OPTIONS | 询问支持的方法 |
TRACE | 回显服务器收到的请求 |
HTTP是无状态协议,使用 Cookie 进行状态管理
HTTP 协议是不保存状态的协议,协议本身不保留之前的一切请求和响应报文的信息,也就是说,无法根据之前的状态进行本次的请求处理。
假设要求登录认证的 Web 页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面不是要再次登录,就是要在每次请求报文中附加参数来管理登录状态。
保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie
的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
请求报文(没有COOKIE信息的状态)
GET /reader/ HTTP/1.1
Host: hackr.jp
响应报文(服务器端生成Cookie 信息)
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache
Set-Cookie: sid=1342077140226724; path=/; expires=Wed,10-Oct-12 07:12:20 GMT
Content-Type: text/plain; charset=UTF-8
请求报文(自动发送保存着的Cookie 信息)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724
HTTP是无连接协议,使用 Keep-alive 维持TCP长连接节省通信量
HTTP是应用层协议,不关注连接,需要借助传输层协议 TCP 进行连接。
HTTP/0.9时代:短连接
每个HTTP请求都要经历一次DNS解析、三次握手、传输和四次挥手。反复创建和断开TCP连接的开销巨大,在现在看来,这种传输方式简直是糟糕透顶。HTTP/1.0时代:持久连接概念提出
人们认识到短连接的弊端,提出了持久连接的概念,在HTTP/1.0中得到了初步的支持。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP 连接状态。客户端在请求header中携带Connection: Keep-Alive
,向服务端请求持久连接。如果服务端接受持久连接,则会在响应header中同样携带Connection: Keep-Alive
,这样客户端便会继续使用同一个TCP连接发送接下来的若干请求。(Keep-Alive的默认参数是[timout=5, max=100],即一个TCP连接可以服务至多5秒内的100次请求)HTTP/1.1时代:持久连接成为默认的连接方式;提出
pipelining(管线化)
概念
HTTP/1.1开始,即使请求header中没有携带Connection: Keep-Alive
,传输也会默认以持久连接的方式进行。目前所有的浏览器都默认请求持久连接,几乎所有的HTTP服务端也都默认开启对持久连接的支持,短连接正式成为过去式。同时,持久连接的弊端
HOLB(Head of Line Blocking)
被提出: 持久连接下一个连接中的请求仍然是串行的,如果某个请求出现网络阻塞等问题,会导致同一条连接上的后续请求被阻塞。所以HTTP/1.1中提出了pipelining(管线化)
概念,即客户端可以在一个请求发送完成后不等待响应便直接发起第二个请求,服务端在返回响应时会按请求到达的顺序依次返回,这样就极大地降低了延迟。然而pipelining(管线化)
并没有彻底解决阻塞,为了让同一个连接中的多个响应能够和多个请求匹配上,响应仍然是按请求的顺序串行返回的。HTTP/2时代:
multiplexing
即多路复用multiplexing
技术能够让多个请求和响应的传输完全混杂在一起进行,通过streamId
来互相区别。这彻底解决了HOLB
问题,同时还允许给每个请求设置优先级,服务端会先响应优先级高的请求。