HTTP (Hypertext transfer protocol) :超文本传输协议,由蒂姆·伯纳斯-李于1989年在欧洲核子研究组织(CERN)所发起。
设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
发展简史
1991年发布HTTP 0.9版
1996年发布1.0版
1997年发布1.1版,目前为止使用最广泛的版本
2015年发布了2.0版,极大的优化了HTTP/1.1的性能和安全性
2018年发布的3.0版,继续优化HTTP/2,激进地使用UDP取代TCP协议
目前,HTTP/3 在2019年9月26日 被 Chrome,Firefox,和Cloudflare支持
HTTP 0.9
概念验证版本
简单到极点,没有请求头,没有状态码,只支持 GET
方法,响应只包含 HTML,且 TCP 连接关闭就会结束。
由于浏览器尚未流行,因此用户需要直接阅读 HTML。可以用它链接到其他资源,所有标签都不会异步请求其他资源。
一个 HTTP 请求就传递了一个完整的、自给自足的页面。
HTTP 1.0
HTTP 1.0 扩展了0.9版,其中主要增加了几个变化:
- 加入HTTP版本号
- 增加请求头header
- 增加状态码。
- 增加
Content-Type
,可以传输其它的文件了。
缺点:
每请求一个资源都要新建一个TCP链接,而且是串行请求,所以,就算网络变快了,打开网页的速度也还是很慢。所以,HTTP 1.0 应该是一个必需要淘汰的协议了。
HTTP/1.1
HTTP/1.1 主要解决了HTTP 1.0的网络性能的问题,以及增加了一些新的东西:
增加
keepalive
来让HTTP重用TCP链接,重用TCP链接可以省了每次请求都要在广域网上进行的TCP的三次握手的巨大开销。这是所谓的“HTTP 长链接”- 然后支持pipeline网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。
- 支持 Chunked Responses ,也就是说,在Response的时候,不必说明
Content-Length
这样,客户端就不能断连接,直到收到服务端的EOF标识。这种技术又叫 “服务端Push模型”,或是 “服务端Push式的HTTP 持久链接” - 增加了 cache control 机制。
- 协议头注增加了 Language, Encoding, Type 等等头,让客户端可以跟服务器端进行更多的协商。
- 增加
[HOST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host)
头,服务器就知道你要请求哪个网站了。因为可以有多个域名解析到同一个IP上,要区分用户是请求的哪个域名,就需要在HTTP的协议中加入域名的信息,而不是被DNS转换过的IP信息。 正式加入了
OPTIONS
方法,其主要用于 CORS – Cross Origin Resource Sharing 应用。HTTP/2
在现在的网络上,一个网页平均需要请求几十次,在 HTTP 1.1 时代浏览器能做的就是多开几个连接(通常是 6 个)进行并行请求,但是单个连接上请求还是一个一个串行发的,而且需要保证其顺序。而 HTTP 2 中可以在一个连接中进行并行请求。HTTP 2 原生支持多个并行请求,因此大大减少了顺序执行的请求的往返程,从而大幅提高速度。
HTTP/2 相比 HTTP 1.1,页面加载速度至少提高了50%以上。
你可以在这个网站测试HTTP2和HTTP1.1的速度差异:https://www.httpvshttps.com/。
另外,HTTP/1.1传输数据时,是以文本的方式,借助耗CPU的zip压缩的方式减少网络带宽,但是耗了前端和后端的CPU。这也是为什么很多RPC协议诟病HTTP的一个原因,就是数据传输的成本比较大。
HTTP/2基本上解决了之前的这些性能问题,其和HTTP/1.1最主要的不同是:HTTP/2是一个二进制协议,增加了数据传输的效率。
- HTTP/2是可以在一个TCP链接中并发请求多个HTTP请求,移除了HTTP/1.1中的串行请求。
- HTTP/2会压缩头,如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分。这就是所谓的HPACK算法
- HTTP/2允许服务端在客户端放cache,又叫服务端push,也就是说,你没有请求的东西,我服务端可以先送给你放在你的本地缓存中。比如,你请求X,我服务端知道X依赖于Y,虽然你没有的请求Y,但我把把Y跟着X的请求一起返回客户端。
HTTP/2 在性能上对HTTP有质的提高,所以,HTTP/2 被已被大量采用
在 Nginx 中开启 HTTP 2.0 非常简单,只需要增加一个 http2 标志即可
listen 443 ssl;
# 改为
listen 443 ssl http2;
如果你担心你的用户用的是旧的客户端,比如 Python 的 requests,暂时还不支持 HTTP 2 的话,那么其实不用担心。如果用户的客户端不支持 HTTP 2,那么连接会自动降级为 HTTP 1.1,保持了后向兼容。
如何查看一个网站是否开启http2
HTTP/3
然而,这个世界没有完美的解决方案,HTTP/2也不例外,其主要的问题是:若干个HTTP的请求在复用一个TCP的连接,底层的TCP协议是不知道上层有多少个HTTP的请求的,所以,一旦发生丢包,造成的问题就是所有的HTTP请求都必需等待这个丢了的包被重传回来,哪怕丢的那个包不是我这个HTTP请求的。
于是HTTP/3把HTTP底层的TCP协议换成了基于UDP的QUIC 协议。
与 HTTP2 在技术上允许未加密的通信不同,QUIC 严格要求加密后才能建立连接。