HTTP协议工作于C/S架构上,是万维网服务器传输超文本到本地客户端的一种应用层协议,全称是:Hyper Text Transfer Protocol(超文本传输协议),HTTP是基于TCP/IP通信协议来传递数据的。HTTP1990年被提出,由于其简洁性、快速性等特点,被广泛应用,并且经过不断的完善和发展,功能也越来越强大,目前已经发展到HTTP/2版本。

一. HTTP/0.9

最早版本发布于1991年,功能极其简单,不涉及数据包的传输,默认使用80端口,只有一个GET请求方法,且服务器只能响应HTML格式的字符串,服务器响应后即关闭连接。

请求:

GET /index.html

响应

<html>
<body>
hello world
</bocy>
</html>

二. HTTP/1.0

19965月,HTTP/1.0发布,引入了POSTHEAD命令,大大增强了交互功能,任何格式的内容都可以发送,为互联网的大发展奠定了基础;同时,除了数据部分,每次通信还要求包含头信息(HTTP header),来描述一些meta数据。

新增功能还包括:状态吗(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

请求格式:

GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5)
Accept: */*

可以看到,请求行末尾添加了协议版本号,后面是协议头的信息,描述客户端的情况。

其中,Accept: */*表明客户端接收任何类型的数据

响应格式:

HTTP/1.0 304 Not Modified
Cache-Control max-age=0, must-revalidate
Date Fri, 10 Feb 2017 06:24:38 GMT
Server apache
Connection Keep-alive <html>
<body>
hello world
</body>
</html>

可以看到回应的数据的:头信息 + 一个空行 + 数据。其中,第一行是状态行,格式为:协议版本 + 状态码 + 状态描述。

常用字段介绍:

1. Content-Type

1.0版规定,头信息必须是ASCII码,后面的数据可以是任何格式,因此,服务器在响应的时候,也要告诉客户端,数据是什么格式。下面是Content-Type字段的常用值:

text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml

另外,这些数值统称为MIME type,每个值包括一级类型和二级类型,之间用斜杠分隔,用户也可以自定义该类型,还可以在尾部使用分号,添加参数。

Content-Type: text/html; charset=utf-8

上面的代码表示,发送的是网页,并且编码是的UTF-8格式。

Accept: */*

上面的代码表示客户端可以接受任何格式的数据。

2. Content-Encoding

发送的数据还可以被压缩后再发送,该字段说明了数据压缩的方法。

Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate

客户端还可以在请求时,用Accept-Encoding字段说明自己可以接受哪些压缩方法。

Accept-Encoding: gzip, deflate

缺点

HTTP/1.0版的主要缺点是,由于TCP的每次连接都需要客户端和服务端进行3次握手,但是连接成功后只能发送一次请求,然后连接就断开了,如果需要多次请求,这样效率就很低。但是,为了解决多次请求效率低下的问题,有一个非标准的connection字段暂时解决了该问题。

Connection: keep-alive

这样就可以复用TCP连接,直到客户端或者服务端主动关闭连接。但是这不是标志字段,不同的实现可能行为不一致,所以是一种暂时的解决方案。

三. HTTP/1.1

19971月,HTTP/1.1版本发布,它进一步完善了HTTP协议,一直到今天还在使用,是最流行的版本;HTTP/1.1新增了许多特性:

新增功能介绍:

1.持久连接

HTTP/1.1默认TCP连接不关闭,可以被多个请求复用,不用声明Connection: keep-alive。客户端可以在最后一个请求时,主动发送Connection: close,明确要求服务器关闭TCP连接,或者不发送,那么客户端和服务器发现对方一段时间没有活动,就会主动关闭连接。目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接。

Connection: close

2.管道机制

HTTP/1.1引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求,这样只是改进了客户端HTTP协议请求的效率,服务器还是按照请求的先后顺序来响应。

3.Content-Length

Content-Length字段显示本次响应的数据长度,如果数据被压缩,则是压缩后的长度。在Connection: keep-alive条件下,Content-Length是必须的;反之,和HTTP/1.0一样,Content-Length不是必须的。

4.分块传输编码

使用Content-Lenght字段的前提条件是,服务器发送响应之前,必须知道响应的数据长度。但是,对于一些耗时的动态操作来说,服务器要等到所有操作完成后,才能发送数据,效率不高。因此,HTTP采用了“流模式(stream)”,即“分块传输编码”(chunked transfer encoding)方式,表明响应的数据长度未定,这样就可以产生一块数据,就发送一块数据,提高服务器的响应效率。

Transfer-Encoding: chunked

这样,只要请求或响应的头信息里有Transfer-Encoding字段,就表明响应将由数量未定的数据组成。

每个非空的数据块之前,都会有一个16禁止的数值,表示这个块的长度;最后一个是大小为0的块,表示本次响应数据发送完了。

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked 25
This is the data in the first chunk 1C
and this is the second one 3
con 8
sequence 0

5.其它特性

新增了许多的请求方式:PUTPATCHOPTIONSDELETETRACE,还增加了Host字段,用来指定服务器的域名,就可以把同一请求发送给不同的网站,为虚拟主机的发展奠定了基础。

缺点

虽然HTTP/1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着,这称为"队头堵塞"(Head-of-line blocking)。

为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。

四. HTTP/2

2015年,HTTP/2发布,主要解决了HTTP1.1的效率不高的问题,新增了二进制协议、多工、数据流、头信息压缩等等功能,具体介绍如下:

1.二进制协议

HTTP/2是一个彻底的二进制协议,头信息和数据都是二进制,统称为frame):头信息帧和数据帧。二进制的优势是:可以定义额外的帧,以适应未来更高级的应用。

2.多工

HTTP/2复用TCP连接,客户端和服务器都可以同时发送多个请求或响应,不用按照顺序一一对应,避免了对头堵塞,实现了双向的、实时的通信。

3.数据流

HTTP/2定义每个请求或响应的所有数据为一个数据流(stream),每个数据流都有一个唯一的编号,数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。协议规定:客户端发出的数据流的ID位奇数,服务器发出的数据流ID为偶数。

另外,数据流发送过程中,客户端和服务器都可以随时发送信号而不用关闭TCP连接,以便其它请求使用。但是HTTP1.1就不行,它取消请求的方式必须的关闭连接。HTTP/2还指定了数据流的优先级,优先级越高,服务器就优先处理。

4.头信息压缩

HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如CookieUser Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。

HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用gzipcompress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

5.服务器推送

HTTP/2允许服务器主动向客户端发送资源,主要是服务器经过预测,把一些客户端可能请求的资源主动发送给客户端,提高用户体验。


本文主要参考阮一峰的HTTP协议入门,版权归阮一峰所有。

参考资料

HTTP协议入门

协议基础

HTTP协议

Journey to HTTP/2

最新文章

  1. 关于css样式2
  2. C# 计算两个字符串的相似度
  3. adroid 目录
  4. iOS学习之事件处理
  5. 注册Model类
  6. 关于Python文档读取UTF-8编码文件问题
  7. WCF-NAT模式访问
  8. iOS面试准备之思维导图
  9. M. Subsequence 南昌邀请赛
  10. 微信 JS-SDK 签名验证
  11. J03-Java IO流总结三 《 FileInputStream和FileOutputStream 》
  12. leetcode题解之分解字符串域名
  13. 怎样注册Docker Hub账号
  14. 【LOJ】#2290. 「THUWC 2017」随机二分图
  15. 如此繁荣的移动webapp开发市场:总结当下的一些移动web开发套件
  16. mysql查询日期相关的
  17. hdu 3729(二分图最大匹配)
  18. virtualenv使用
  19. Dreams save us. Dreams lift us up and transform us into something better.
  20. 【win10激活问题】 从【win10专业工作站版】转为 数字许可证的【win10专业版】

热门文章

  1. Hadoop出现的错误及处理
  2. JAVA金额按比例分摊,零头处理
  3. Java虚拟机:如何判定哪些对象可回收?
  4. c++动态内存管理
  5. ServerSocket简单例题
  6. jenkins IOS- ad-hoc 打包
  7. Unity 工作经历+近期面试经历
  8. (转)Spring中ThreadLocal的认识
  9. 【ES】ElasticSearch初体验之使用Java进行最基本的增删改查~
  10. linux c++如何学习