[译] HTTP简史

简介

超文本传输协议(HTTP)是 Internet 上最广泛和普遍采用的应用程序协议之一:它是客户端和服务器之间的通用语言,支持现代 Web。从简单的单一关键字和文档路径开始,它已再也不是浏览器的专属,并且适用于几乎全部链接互联网的软件和硬件应用程序的协议。html

在本章中,咱们将简要介绍 HTTP 协议的演变。对不一样 HTTP 语义的完整讨论超出了本书的范围,可是理解 HTTP 的关键设计变动以及每一个变动背后的动机将为咱们讨论 HTTP 性能提供必要的背景知识,特别是本文中说起的 HTTP/2 即将进行的许多改进。前端

HTTP 0.9:单线协议

Tim Berners-Lee 最初的 HTTP 提案在设计时考虑到了 简单性,以帮助他支撑他的另外一个新生想法:万维网。该策略彷佛有效:有抱负的协议设计者,请注意android

1991 年,Berners-Lee 概述了新协议产生的动机并列出了几个高级设计目标:文件传输功能、请求索引搜索超文本存档的能力、格式协商以及将客户端引用到另外一个服务器的能力。为了证实该理论的实际应用,他构建了一个简单的原型,它实现了所提议功能的一小部分:ios

  • 客户端请求是单个 ASCII 字符串。
  • 客户请求由回车(CRLF)终止。
  • 服务器响应是 ASCII 字符流。
  • 服务器响应是一种超文本标记语言(HTML)。
  • 文档传输完成后终止链接。

其实并无那么复杂,这些规则启用的是一个一些 Web 服务器当前依然支持的、很是简单的而且 Telnet 友好的协议:nginx

$> telnet google.com 80

Connected to 74.125.xxx.xxx

GET /about/

(hypertext response)
(connection closed)
复制代码

请求由单行:GET 方法和所请求文档的路径组成。响应是单个超文本文档 — 没有头部或任何其余元数据,只有 HTML,它真的不能再简单了。此外,因为先前的交互是预期协议的子集,所以它私下里也被叫作 HTTP/0.9。其他的,正如他们所说,是历史。git

从1991年这些不起眼的开始,HTTP 开始了本身的生命,并在将来几年迅速发展。让咱们快速回顾一下 HTTP/0.9 的功能:程序员

  • 客户端 - 服务器,请求 - 响应协议。
  • ASCII 协议,运行在 TCP / IP 连接之上。
  • 旨在传输超文本文档(HTML)。
  • 每次请求后,服务器和客户端之间的链接都将关闭。

小提示:现阶段流行的 Web 服务器,如 Apache 和 Nginx,仍然有一部分支持 HTTP/0.9 协议,由于它真的特别简单!若是您感到好奇,请打开 Telnet 会话并尝试经过 HTTP/0.9 访问 google.com 或您本身喜欢的网站,并检查此早期协议的行为和限制。github

HTTP/1.0: 协议的快速发展和信息 RFC

1991年至1995年期间是 HTML 规范的快速发展的阶段,浏览器诞生,面向消费者的公共互联网基础设施出现并快速增加。web

完美风暴:20 世纪 90 年代初的互联网热潮

在 Tim Berner-Lee 最初的浏览器原型的基础上,国家超级计算应用中心(NCSA)的一个团队决定实现他们本身的版本。这标志着,第一个流行的浏览器诞生了:NCSA Mosaic。1994 年 10 月,NCSA 团队的一名程序员 Marc Andreessen 与 Jim Clark 合做建立了 Mosaic Communications。该公司后来更名为 Netscape(网景),并于 1994 年 12 月发布了 Netscape Navigator 1.0。从那时开始,一切已经很明朗了,万维网不只仅是一个学术热点,它必将引发 更多的 关注。后端

实际上,同年第一次万维网会议在瑞士日内瓦举办,以帮助指导 HTML 的发展为目的的万维网联盟(W3C)也由此诞生。在同一时期,在 IETF 内部同期创建了 HTTP 工做组(HTTP-WG),专一于改进 HTTP 协议。直到今天,他们依旧是互联网的重要团队,继续推进互联网的进化。

最后,为了创造完美的风暴,CompuServe 、AOL 和 Prodigy 在1994-1995年开始向公众提供拨号上网服务。凭借这股互联网浪潮,Netscape 在1995年8月9日以很是成功的 IPO 创造了历史 — 互联网热潮已经到来,每一个人都想要分得一瓢羹!

愈来愈多的公共网站上的使用案例代表大众对于新兴网络的功能需求在不断增长,这很快暴露了 HTTP/0.9 的许多根本限制:咱们须要的协议不只能够提供超文本文档,还能够提供有关请求和响应的更丰富的元数据、启用内容协商等。对此,新兴的 Web 开发人员社区的回应方式是,经过“实现,部署,并看是否有人开始采用它”这一专门的过程,来制做大批实验性质的 HTTP 服务器和客户端。

从这段快速的实验期开始,一系列最佳的实践和常见的模式开始出现,1996 年 5 月,HTTP 工做组(HTTP-WG)发布了 RFC 1945,它记录了许多 HTTP/1.0 不规范但却“常见”的实现方法。请注意,这只是一个信息 RFC:HTTP/1.0 ,由于咱们知道它不是正式规范或 Internet 标准!

话虽如此,但 HTTP/1.0 请求实例看起来却很是熟悉:

$> telnet website.org 80

Connected to xxx.xxx.xxx.xxx

GET /rfc/rfc1945.txt HTTP/1.0 1⃣️
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Accept: */*

HTTP/1.0 200 OK 2⃣️
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84

(plain-text response)
(connection closed)
复制代码

1⃣️ 具备HTTP版本号的请求行,后接请求头

2⃣️具备响应状态码,后接响应头

前面的变化尽管不仅是 HTTP/1.0 功能的详尽列表,但它确实说明了一些关键的协议更改:

  • 请求可能包含多个换行符分隔的头部字段。
  • 响应对象以响应状态行为前缀。
  • 响应对象有本身的一组换行符分隔的头部字段。
  • 响应对象不限于超文本。
  • 每次请求后,服务器和客户端之间的链接都将关闭。

请求和响应头都应保证是 ASCII 编码,但响应对象自己能够是任何类型:HTML 文件、纯文本文件、图像或任何其余内容类型。所以,HTTP 的“超文本传输​​”部分在新特性引入后不久就变得不那么恰当了。实际上,HTTP已经迅速发展成为 超媒体 传输,但原始名称仍然存在。

除了媒体类型协商以外,RFC 还记录了许多其余经常使用功能:内容编码,字符集支持,多部分类型,受权,缓存,代理行为,日期格式等。

小提示:现在,Web 上的几乎全部服务器均可以而且仍将使用 HTTP/1.0。除此以外,到如今为止,你应该更为了解了吧!每一个请求须要新的 TCP 链接会对 HTTP/1.0 形成严重的性能损失。参考:三次握手,以及慢启动

HTTP/1.1:Internet 标准

将 HTTP 转变为官方 IETF 互联网标准的工做与围绕 HTTP/1.0 的文档工做并行进行,并发生在大约四年的时间内:1995 年至 1999 年。事实上,第一个正式的 HTTP/1.1 标准定义于 RFC 2068,在 HTTP/1.0 发布大约六个月后于 1997 年 1 月正式发布。两年半以后,即 1999 年 6 月,标准中包含了许多改进和更新,并做为 RFC 2616 发布。

HTTP/1.1 标准解决了早期版本中发现的许多协议歧义,并引入了许多关键性能优化:keep-alive 链接,分块编码传输,字节范围请求,附加缓存机制,传输编码和管道式请求。

有了这些能力,咱们如今能够检查由任何现代 HTTP 浏览器和客户端执行的典型 HTTP/1.1 会话:

$> telnet website.org 80
Connected to xxx.xxx.xxx.xxx

GET /index.html HTTP/1.1 1⃣️

Host: website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK 2⃣️

Server: nginx/1.0.11
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Via: HTTP/1.1 GWA
Date: Wed, 25 Jul 2012 20:23:35 GMT
Expires: Wed, 25 Jul 2012 20:23:35 GMT
Cache-Control: max-age=0, no-cache
Transfer-Encoding: chunked

100 3⃣️

<!doctype html>
(snip)

100
(snip)

0 4⃣️

GET /favicon.ico HTTP/1.1 5⃣️

Host: www.website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: */*
Referer: http://website.org/
Connection: close 6⃣️

Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK 7⃣️

Server: nginx/1.0.11
Content-Type: image/x-icon
Content-Length: 3638
Connection: close
Last-Modified: Thu, 19 Jul 2012 17:51:44 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Via: HTTP/1.1 GWA
Date: Sat, 21 Jul 2012 21:35:22 GMT
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Etag: W/PSA-GAu26oXbDi

(icon data)
(connection closed)
复制代码

1⃣️ 请求 HTML 文件,包含编码,字符集和 cookie 元数据

2⃣️ 原始 HTML 请求的分块响应

3⃣️ 块中的八位字节数表示为 ASCII 十六进制数(256 字节)

4⃣️ 分块流响应结束

5⃣️ 请求在同一 TCP 链接上建立的图标文件

6⃣️ 通知服务器不会重用链接

7⃣️ 图标响应,而后关闭链接

哎呀,那里有太多事情发生!第一个也是最明显的区别是咱们有两个对象请求,一个用于HTML页面,另外一个用于图像,二者都经过单个链接传递。这是链接 keep-alive 的实际应用,它容许咱们重用现有的 TCP 链接,以便对同一主机发出多个请求,并提供更快的最终用户体验。参阅 TCP 的优化

要终止持久链接,请注意第二个客户端请求 close 经过 Connection 请求头向服务器发送显式指令。相似地,一旦传输响应,服务器就能够通知客户端关闭当前 TCP 链接的意图。从技术上讲,任何一方均可以在没有此类信号的状况下终止 TCP 链接,但客户端和服务器应尽量提供它以在双方上实现更好的链接重用策略。

小提示:HTTP/1.1 下将 HTTP 协议的语法更改成默认状况使用链接 keep-alive。这意味着,除非另有说明(经过 Connection: close 头部),不然服务器应默认保持链接处于打开状态。

可是,一样的功能也被反向移植到 HTTP/1.0 并经过 Connection: Keep-Alive 头部启用。所以,若是您使用 HTTP/1.1,从技术上讲,您不须要 Connection: Keep-Alive 请求头,但许多客户端仍然选择提供它。

此外,HTTP/1.1 协议添加了内容,编码,字符集,甚至语言协商,传输编码,缓存指令,客户端 cookie,以及能够在每一个请求上协商的十几种其余功能。

咱们不打算详述每一个 HTTP/1.1 功能的语义,由于它彻底足够写成一本专业的书了,并且事实上也已经有不少相似的优秀书籍了。相反,前面的示例能够很好地说明 HTTP 的快速进展和演变,以及每一个客户端到服务器之间交换的错综复杂。那里有不少事情发生!

小提示:有关HTTP协议全部内部工做原理的详细参考,请查看 David Gourley 和 Brian Totty 撰写的 O'Reilly 出版的 HTTP:The Definitive Guide

HTTP/2: 提升运输性能

自发布以来,RFC 2616 已经成为互联网空前增加的基础:数十亿台各类形状和大小的设备,从台式电脑到咱们口袋里的小型网络设备,以及咱们生活中都已离不开的天天都会用 HTTP 来传送新闻、视频以及数以百万计的其余网络应用程序。

最初用于检索超文本的简单单行协议最终演变为通用的超媒体传输,或许十年以后甚至可用于为您能想象的任何需求提供支持。无处不在的服务器以及协议在客户端中的普遍可用性,意味着如今许多应用程序都是专门在 HTTP 之上设计和部署的。

须要一个协议来控制你的咖啡壶?RFC 2324 已经涵盖了超文本咖啡壶控制协议(HTCPCP/1.0)—— 本来是 IETF 的愚人节玩笑,却渐渐的在咱们新的超链接世界中再也不是“玩笑”。

超文本传输协议(HTTP)是用于分布式协做超媒体信息系统的应用程序级协议。它是一种通用的无状态协议,能够经过扩展其请求方法,错误代码和头部,用于拓展其用于超文本以外的许多任务,例如名称服务器和分布式对象管理系统。HTTP 的一个特性是数据表示的输入和协商,容许系统独立于正在传输的数据而构建。

RFC 2616:HTTP/1.1,1999 年 6 月

HTTP 协议的简捷性使其最初被普遍采用和快速发展成为可能。事实上,如今发现使用 HTTP 做为主要控制和数据协议的嵌入式设备(传感器,执行器和咖啡壶)并不罕见。但在其自身成功的重压下,随着咱们愈来愈多地继续将咱们的平常互动转移到网络 —— 社交、电子邮件、新闻、视频以及愈来愈多的我的和工做空间 —— 它也开始显示出有心无力的迹象。用户和 Web 开发人员如今都要求 HTTP/1.1 提供近乎实时的响应和协议性能,若是不作出修改,它就没法知足需求。

为了应对这些新挑战,HTTP 必须继续发展,所以 HTTPbis 工做组在2012年初宣布了一项针对 HTTP/2 的新计划:

新的实现专一于在保留 HTTP 的语义的基础上,摒弃 HTTP/1.x 消息框架和语法的遗留问题,这些问题已被肯定为妨碍性能,并且极易形成底层传输的误用。

工做组将基于 HTTP 当前的语义以及有序的全双工模式中设计新的规范。与 HTTP/1.x 同样,主要目标传输是 TCP,但应该可使用其余传输。

HTTP/2 章程,2012 年 1 月

HTTP/2 的主要关注点是提升传输性能并实现更低的延迟和更高的吞吐量。主要的版本增幅听起来是一个很大的步骤,就性能而言,它将是一个重要的步骤,但重要的是要注意,没有任何高级协议语义受到影响:全部 HTTP 头,值和用户场景都是相同的。

任何现有的网站或应用程序均可以而且将经过 HTTP/2 传送而无需作出任何修改:您无需变动您的应用程序以利用 HTTP/2。HTTP 服务器将广泛使用 HTTP/2,但这应该成为大多数用户的透明升级。若是工做组实现其目标,惟一的区别应该是咱们的应用程序以更低的延迟和更好的网络连接利用率交付!

话虽如此,让咱们不要过于超前。在咱们开始使用新的 HTTP/2 协议功能以前,值得退一步并检查咱们现有的 HTTP/1.1 部署和性能最佳实践。HTTP/2 工做组正在新规范上取得快速进展,但即便最终标准已经完成并准备就绪,咱们仍然必须在可预见的将来支持旧的 HTTP/1.1 客户端。实际上,有可能会是十年或更长时间。

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索