简介
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个请求-响应协议,是基于TCP/IP协议之上的应用层协议。
通常,由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端的请求。一旦收到请求,服务器会向客户端返回一个状态,比如”HTTP/1.1 200 OK”,以及返回的内容,如请求的文件、错误消息、或者其它信息。
工作原理
请求/响应的步骤
- 客户端连接到Web服务器
- 发送HTTP请求
- 服务器接受请求并返回HTTP响应
- 释放连接TCP连接
- 客户端浏览器解析HTML内容
无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。
HTTP请求格式
包含请求行、请求头、空行和请求数据四个部分
HTTP响应格式
包含状态行,响应头部,空行,响应数据四个部分
HTTP请求方法
1. GET
请求指定的页面信息,并返回实体主体。
2. HEAD
类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
3. POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。
4. PUT
从客户端向服务器传送的数据取代指定的文档的内容。
5. DELETE
请求服务器删除指定的页面。
6. CONNECT
HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
7. OPTIONS
允许客户端查看服务器的性能。
8. TRACE
回显服务器收到的请求,主要用于测试或诊断
9. PATCH
是对 PUT 方法的补充,用来对已知资源进行局部更新
HTTP版本介绍
HTTP/0.9
1990年问世,那时的HTTP并没有作为正式的标准被建立,这时的HTTP其实含有HTTP/1.0之前版本的意思,那时候还有严重设计缺陷,只支持GET方法,很快被HTTP/1.0取代。
并且协议还规定,服务器只能回应HTML格式的字符串,不能回应别的格式,当服务器发送完毕,就关闭TCP连接。
HTTP/1.0
优点
- 任何格式的内容都可以发送;
- 除了GET命令,还引入了POST命令和HEAD命令;
- HTTP请求和回应的格式,每次通信都必须包括头信息(HTTP header),用来描述一些元数据;
- 其他的新增功能还包括状态码、多字符集支持、多部分发送、权限、缓存、内容编码等。
缺点
性能比较差,每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭。
HTTP/1.1
优点
- 引入了持久连接;
- 引入了管道机制,即在同一个TCP连接里面,客户端可以同时发送多个请求;
- 将Content-length字段的作用进行扩充,即声明本次回应的数据长度;
- 采用分块传输编码,对于一些很耗时的动态操作,服务器需要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用”流模式”(stream)取代”缓存模式”(buffer);
- 新增了许多请求方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。另外,客户端请求的头信息新增了Host字段,用来指定服务器的域名。
缺点
虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为”队头堵塞”(Head-of-line blocking)。
为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。
HTTP/2.0
特点
在不改动 HTTP 语义、方法、状态码、URI及首部字段的情况下,大幅度提高了 Web 性能。
点击此处对比 HTTP/2.0 与 HTTP/1.x 的速度,链接地址。
二进制传输
HTTP2.0 中所有加强性能的核心是二进制传输,其引入了新的编码机制,所有传输的数据都会被分割,并采用二进制格式编码。
为了保证 HTTP 不受影响,那就需要在应用层(HTTP2.0)和传输层(TCP or UDP)之间增加一个二进制分帧层。在二进制分帧层上,HTTP2.0 会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码,其中 HTTP1.x 的首部信息会被封装到 Headers 帧,而 Request Body 则封装到 Data 帧。
多路复用
在HTTP1.0 中,当页面需要请求很多资源的时候,队头阻塞(Head of line blocking)会导致在达到最大请求时,资源需要等待其他资源请求完成后才能继续发送。
HTTP2.0 中,有两个概念非常重要:帧(frame)和流(stream)。
帧是最小的数据单位,每个帧会标识出该帧属于哪个流,流是多个帧组成的数据流。
所谓多路复用,即在一个 TCP 连接中存在多个流,即可以同时发送多个请求,对端可以通过帧中的表示知道该帧属于哪个请求。在客户端,这些帧乱序发送,到对端后再根据每个帧首部的流标识符重新组装。 通过该技术,可以避免 HTTP 旧版本的队头阻塞问题,极大提高传输性能。
Header压缩
在 HTTP1.0 中,我们使用文本的形式传输header,在header中携带cookie的话,每次都需要重复传输几百到几千的字节,这着实是一笔不小的开销。
在 HTTP2.0 中,我们使用了HPACK(HTTP2头部压缩算法)压缩格式对传输的 header 进行编码,减少了 header 的大小。并在两端维护了索引表,用于记录出现过的header,后面在传输过程中就可以传输已经记录过的header的键名,对端收到数据后就可以通过键名找到对应的值。
服务器Push
在HTTP2.0中,服务端可以在客户端某个请求后,主动推送其他资源。
可以想象一下,某些资源客户端是一定会请求的,这时就可以采取服务端push的技术,提前给客户端推送必要的资源,就可以相对减少一点延迟时间。