整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTTP 简史

HTTP 简史

本文中,我们将简要回顾 HTTP 协议的发展历史。对 HTTP 不同语义的完整讨论超出了本文的范围,但理解 HTTP 的关键设计变更以及每个变更背后的动机将为我们讨论 HTTP 性能提供必要的背景

-- Ilya Grigorik

译注:本文来源于 2013 年出版的《 High Performance Browser Networking 》的第九章,因此有些信息略有过时。事实上,现在 HTTP/2 已经有相当的不是,而新的 HTTP/3 也在设计和标准制定当中。

介绍

超文本传输协议(Hypertext Transfer Protocol)(HTTP)是互联网上最普遍和广泛采用的应用程序协议之一。它是客户端和服务器之间的通用语言,支持现代 Web。从最初作为单个的关键字和文档路径开始,它已成为不仅仅是浏览器的首选协议,而且几乎是所有连接互联网硬件和软件应用程序的首选协议。

在本文中,我们将简要回顾 HTTP 协议的发展历史。对 HTTP 不同语义的完整讨论超出了本文的范围,但理解 HTTP 的关键设计变更以及每个变更背后的动机将为我们讨论 HTTP 性能提供必要的背景,特别是在 HTTP/2 中即将进行的许多改进。

HTTP 0.9: 单行协议

蒂姆·伯纳斯·李(Tim Berners-Lee) 最初的 HTTP 提案在设计时考虑到了简单性,以帮助他采用他的另一个新想法: 万维网(World Wide Web)。这个策略看起来奏效了:注意,他是一个有抱负的协议设计者。

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

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

然而,即使这听起来也比实际复杂得多。这些规则支持的是一种非常简单的,对 Telnet 友好的协议,一些 Web 服务器至今仍然支持这种协议:

$> telnet google.com 80

Connected to 74.125.xxx.xxx

GET /about/

(hypertext response)

(connection closed)

请求包含这样一行:GET 方法和请求文档的路径。响应是一个超文本文档,没有标题或任何其他元数据,只有 HTML。真的是再简单不过了。此外,由于之前的交互是预期协议的子集,因此它获得了一个非官方的 HTTP 0.9 标签。其余的,就像他们所说的,都是历史。

从 1991 年这些不起眼的开始,HTTP 就有了自己的生命,并在接下来几年里迅速发展。让我们快速回顾一下 HTTP 0.9 的特性:

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

流行的 Web 服务器,如 Apache 和 Nginx,仍然支持 HTTP 0.9 协议,部分原因是因为它没有太多功能!如果你感兴趣,打开 Telnet 会话并尝试通过 HTTP 0.9 访问 google.com 或你最喜欢的网站,并检查早期协议的行为和限制。

HTTP/1.0: 快速增长和 Informational RFC

1991 年至 1995 年期间,HTML 规范和一种称为 “web 浏览器”的新型软件快速发展,面向消费者的公共互联网基础设施也开始出现并快速增长。

完美风暴:1990 年代初的互联网热潮

基于蒂姆·伯纳斯·李最初的浏览器原型,美国国家超级计算机应用中心(NCSA)的一个团队决定实现他们自己的版本。就这样,第一个流行的浏览器诞生了:NCSA Mosaic。1994 年 10 月,NCSA 团队的一名程序员 Marc Andreessen 与 Jim Clark 合作创建了 Mosaic Communications,该公司后来改名为 Netscape(网景),并于 1994 年 12 月发布了 Netscape Navigator 1.0。从这一点来说,已经很清楚了,万维网已经不仅仅是学术上的好奇心了。

实际上,同年在瑞士日内瓦组织了第一次万维网会议,这导致 万维网联盟(World Wide Web Consortium)(W3C)的成立,以帮助指导 HTML 的发展。同样,在 IETF 内部建立了一个并行的 HTTP 工作组(HTTP Working Group)(HTTP-WG),专注于改进 HTTP 协议。后来这两个团体一直对 Web 的发展起着重要作用。

最后,完美风暴来临,CompuServe,AOL 和 Prodigy 在 1994-1995 年的同一时间开始向公众提供拨号上网服务。凭借这股迅速的浪潮,Netscape 在 1995 年 8 月 9 日凭借其成功的 IPO 创造了历史。这预示着互联网热潮已经到来,人人都想分一杯羹!

不断增长的新 Web 所需功能及其在公共网站上的应用场景很快暴露了 HTTP 0.9 的许多基础限制:我们需要一种能够提供超文本文档、提供关于请求和响应的更丰富的元数据,支持内容协商等等的协议。相应地,新兴的 Web 开发人员社区通过一个特殊的过程生成了大量实验性的 HTTP 服务器和客户端实现来回应:实现,部署,并查看其他人是否采用它。

从这些急速增长的实验开始,一系列最佳实践和常见模式开始出现。1996 年 5 月, HTTP 工作组(HTTP Working Group)(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 ?

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

Accept: */*

HTTP/1.0 200 OK ?

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)

  • ? 请求行有 HTTP 版本号,后面跟请求头
  • ? 响应状态,后跟响应头

前面的交互并不是 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 标准解决了早期版本中发现的许多协议歧义,并引入了一些关键的性能优化:保持连接,分块编码传输,字节范围请求,附加缓存机制,传输编码和请求管道。

有了这些功能,我们现在可以审视一下由任何现代 HTTP 浏览器和客户端执行的典型 HTTP/1.1 会话:

$> telnet website.org 80

Connected to xxx.xxx.xxx.xxx

GET /index.html HTTP/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 ?

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 ?

<!doctype html>

(snip)

100

(snip)

0 ?

GET /favicon.ico HTTP/1.1 ?

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 ?

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 ?

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)

  • ? 请求的 HTML 文件,包括编、字符集和 cookie 元数据
  • ? 原始 HTML 请求的分块响应
  • ? 以 ASCII 十六进制数字(256 字节)表示块中的八位元的数量
  • ? 分块流响应结束
  • ? 在相同的 TCP 连接上请求一个图标文件
  • ? 通知服务器不再重用连接
  • ? 图标响应后,然后关闭连接

哇,这里发生了很多事情!第一个也是最明显的区别是我们有两个对象请求,一个用于 HTML 页面,另一个用于图像,它们都通过一个连接完成。这就是保持连接的实际应用,它允许我们重用现有的 TCP 连接到同一个主机的多个请求,提供一个更快的最终用户体验。参见 TCP 优化 。

要终止持久连接,注意第二个客户端请求通过 Connection 请求头向服务器发送显示的 close。类似地,一旦传输响应,服务器就可以通知客户端关闭当前 TCP 连接。从技术上讲,任何一方都可以在没有此类信号的情况下终止 TCP 连接,但客户端和服务器应尽可能提供此类信号,以便双方都启用更好的连接重用策略。

HTTP/1.1 改变了 HTTP 协议的语义,默认情况下使用保持连接。这意味着,除非另有说明(通过 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 共同撰写的权威指南: The Definitive Guide。

HTTP/2: 提高传输性能

RFC 2616 自发布以来,已经成为互联网空前增长的基础:数十亿各种形状和大小的设备,从台式电脑到我们口袋里的小型网络设备,每天都在使用 HTTP 来传送新闻,视频,在我们生活中的数百万的其他网络应用程序都在依靠它。

一开始是一个简单的,用于检索超文本的简单协议,很快演变成了一种通用的超媒体传输,现在十年过去了,它几乎可以为你所能想象到的任何用例提供支持。可以使用协议的服务器无处不在,客户端也可以使用协议,这意味着现在许多应用程序都是专门在 HTTP 之上设计和部署的。

需要一个协议来控制你的咖啡壶?RFC 2324 已经涵盖了超文本咖啡壶控制协议(HTCPCP/1.0)- 它原本是 IETF 在愚人节开的一个玩笑,但在我们这个超链接的新世界中,它不仅仅意味着一个玩笑。

超文本传输协议(HTTP)是一个应用程序级的协议,用于分布式、协作、超媒体信息系统。它是一种通用的、无状态的协议,可以通过扩展请求方法、错误码和头,用于超出超文本之外的许多任务,比如名称服务器和分布式对象管理系统。HTTP 的一个特性是数据表示的类型和协商,允许独立于传输的数据构建系统。

RFC 2616: HTTP/1.1, June 1999

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

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

已经有一个协议中出现了新的实现经验和兴趣,该协议保留了 HTTP 的语义,但是没有保留 HTTP/1.x 的消息框架和语法,这些问题已经被确定为妨碍性能和鼓励滥用底层传输。

工作组将使用有序的双向流中生成 HTTP 当前语义的新表达式的规范。与 HTTP/1.x 一样,主要传输目标是 TCP,但是应该可以使用其他方式传输。

HTTP/2 charter, January 2012

HTTP/2 的主要重点是提高传输性能并支持更低的延迟和更高的吞吐量。主要的版本增量听起来像是一个很大的步骤,但就性能而言,它将是一个重大的步骤,但重要的是要注意,没有任何高级协议语义收到影响:所有的 HTTP 头,值和用例是相同的。

任何现有的网站或应用程序都可以并且将通过 HTTP/2 传送而无需修改。你无需修改应用程序标记来利用 HTTP/2。HTTP 服务器将来一定会使用 HTTP/2,但这对大多数用户来说应该是透明的升级。如果工作组实现目标,唯一的区别应该是我们的应用程序以更低的延迟和更好的网络连接利用率来传送数据。

话虽如此,但我们不要走的太远了。在讨论新的 HTTP/2 协议功能之前,有必要回顾一下我们现有的 HTTP/1.1 部署和性能最佳实践。HTTP/2 工作组正在新规范上取得快速的进展,但即使最终标准已经完成并准备就绪,在可预见的未来,我们仍然必须支持旧的 HTTP/1.1 客户端,实际上,这得十年或更长时间。


via: https://hpbn.co/brief-history-of-http/#http-09-the-one-line-protocol

作者: Ilya Grigorik 选题: lujun9972 译者: MjSeven 校对: wxy

本文由 LCTT 原创编译, Linux中国 荣誉推出

点击“了解更多”可访问文内链接

AsciidocFX是一个功能强大的AsciiDoc编辑器和工具链,它使用JavaFX 21构建。AsciiDoc是一种轻量级标记语言,用于编写文档、书籍、幻灯片和其他形式的出版物。AsciidocFX提供了一个直观的用户界面,让用户能够轻松地创建、编辑和导出AsciiDoc文档。

特性

AsciidocFX具有许多令人印象深刻的特性,使其成为AsciiDoc文档处理的理想选择。下面是该工具的一些突出特性:

1. 强大的编辑功能

AsciidocFX提供了丰富的编辑功能,使用户能够高效地编写AsciiDoc文档。编辑器具有语法高亮显示、自动完成、即时预览等功能,可帮助用户准确无误地编写和格式化文档。

2. 多格式导出

AsciidocFX支持将AsciiDoc文档导出为多种格式,包括PDF、Epub、Mobi和HTML。这使得用户能够根据需要灵活地生成不同格式的文档,并轻松地与其他人共享或发布。

3. 自定义主题和样式

该工具允许用户自定义文档的外观和样式。用户可以选择不同的主题和样式表,以满足其特定需求,并创建专业而个性化的文档。

4. 图形化界面

AsciidocFX提供了一个直观的图形化界面,使用户能够轻松管理和组织复杂的AsciiDoc项目。用户可以在一个集成的环境中创建、编辑和预览文档,提高工作效率并减少错误。

5. 插件生态系统

AsciidocFX支持插件扩展,用户可以根据自己的需求选择和安装各种插件。这使得用户能够根据自己的工作流程和偏好定制编辑器,并添加额外的功能和集成。

6. 多平台支持

AsciidocFX可在多个操作系统上运行,包括Windows、Mac和Linux。这使得用户可以在他们喜欢的操作系统上使用这个功能强大的工具,并与不同平台上的其他人方便地协作。

使用示例

以下是使用AsciidocFX创建AsciiDoc文档的简单示例流程:

  • 1. 打开AsciidocFX编辑器,并创建一个新的AsciiDoc项目。
  • 2. 在编辑器中编写AsciiDoc文档,使用丰富的编辑功能进行格式化和排版。
  • 3. 预览文档的实时预览,以便查看最终输出的外观。
  • 4. 根据需要选择导出格式,如PDF、Epub、Mobi或HTML。
  • 5. 配置导出选项,如样式、主题和布局。
  • 6. 导出文档到所选的格式,并保存到本地或指定的目录。
  • 7. 完成后,可以将生成的文档共享给其他人或发布到适当的平台。


总结

AsciidocFX是一个强大而灵活的AsciiDoc编辑器和工具链,它通过使用JavaFX 21提供了一个直观的用户界面和丰富的功能。它支持多种格式的导出,自定义主题和样式,插件扩展以及跨平台的多平台支持。无论是撰写文档、编写书籍、创建幻灯片还是生成其他形式的出版物,AsciidocFX都是一个值得考虑的选择。它简化了AsciiDoc文档处理的流程,提供了便捷的编辑环境和导出选项,使用户能够高效地创建专业级的文档作品。

项目地址:https://github.com/asciidocfx/AsciidocFX

我们知道HTTP是浏览器中最重要且使用最多的协议,它不仅是浏览器与服务端的通信语言,更是互联网的基石。随着浏览器的不断更新迭代,HTTP为了适应技术的更新也在不断进化,学习HTTP的最佳途径就是从浏览器的发展视角来了解HTTP的演进:即将完成使命的HTTP/1、正在向我们走来的HTTP/2、未来的HTTP/3


HTTP发展史

HTTP 是浏览器与服务端最主要的通信协议

20 世纪 60 年代,美国国防部高等研究计划署(ARPA)建立了 ARPA 网,这被认为是互联网的起源。70 年代,研究人员基于对 ARPA 网的实践和思考,发明出了著名的 TCP/IP 协议。该协议具有良好的分层结构和稳定的性能,并在 80 年代中期进入了 UNIX 系统内核,促使更多的计算机接入了网络。

1989 年,蒂姆伯纳斯-李博士发表了一篇论文,提出了在互联网上构建超链接文档系统的构想。在篇文章中他确立了三项关键技术:URI、HTML、HTTP。

HTTP/0.9

1991年HTTP(HyperText Transfer Protocol,超文本传输协议)正式诞生,万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(IETF)制定了 HTTP 0.9 标准。该协议诞生之初的作用是传输超文本内容HTML,并且只支持GET请求。

协议定义了客户端发起请求、服务端响应请求的通信模式。所以当时的请求报文只有一行:

GET + 请求的文件路径

服务端在收到请求后会返回一个以 ASCII 字符流编码的 HTML 文档。

请求: GET /index.html

响应: <html><body>Hello HTTP/0.9</body></html>

流程:

  • 客户端和服务端建立TCP连接。
  • 客户端发送GET请求到服务端,请求index.html页面的数据。
  • 服务端发送完响应,关闭TCP连接。

特点: 简单,一个请求需要一个连接。

HTTP/0.9 虽然简单,但是它充分验证了 Web 服务的可行性

  • 首先它只有一个命令GET。
  • 它没有HEADER等描述数据的信息。因为这个时候的请求非常简单,它需要达到的目的也非常简单,没有那么多数据格式。
  • 服务器发送完内容之后,就关闭TCP连接。这里需要注意一点,这里的TCP连接和http请求是不一样的。http请求和TCP连接不是一个概念。一个http请求通过TCP连接发送,而一个TCP连接里面可以发送很多个http请求(HTTP/0.9不能这么做,但是HTTP/1.1可以这么做,而且在HTTP/2这方面会更大程度地优化,来提高HTTP协议传输的效率以及服务器的性能)

HTTP/1.0

随着互联网的发展,之前的HTTP/0.9已经无法满足用户需求了,浏览器希望通过HTTP来传输脚本、样式、图片、音视频等不同类型的文件,所以在1996年HTTP进行了一次版本更新:

  • 增加了HEAD、POST等新方法
  • 增加了响应状态码,标记可能的错误原因
  • 引入了协议版本号概念
  • 引入了HTTP header的概念,让HTTP处理请求和响应更加灵活
  • 传输的数据不再局限于文本

请求: 第一行请求命令+版本信息,后面的多行为头信息

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

响应: 响应头信息 + 空行(\r\n) + 数据部分

HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 2345
Expires: Thu, 05 Dec 2020 16:00:00 GMT
Last-Modified: Wed, 5 August 2020 15:55:28 GMT
Server: Apache 0.84

<html>
   <body>Hello World</body>
</html>

HTTP/1.0最主要的缺点还是跟HTTP/0.9一样,每一个TCP连接只能发送一个HTTP请求,服务器发送完响应,就关闭连接。如果后面需要请求新的数据,则需要再次建立TCP连接,但是TCP建立连接的三次握手成本比较高,并且TCP连接初始的时候发送数据的速度相对较慢,有一个慢启动和拥塞避免的阶段。极端情况,如果每次请求的数据很少,但是请求很频繁,这样每次请求很少的数据都需要建立连接然后断开。

为了解决这个问题,在1.0版本使用了一个非标准的Connection头部字段。当客户端再请求头部信息里面带上Connection:keep-alive的时候,服务器在发送完响应数据之后,就不会断开TCP连接了,从而达到复用同一个TCP连接的目的。但是由于不是标准字段,不同的实现可能导致表现得不一致,因此不能从根本上解决这个问题。

HTTP/1.0最核心的改变是增加了头部设定,头部内容以键值对的形式设置。请求头部通过 Accept 字段来告诉服务端可以接收的文件类型,响应头部再通过 Content-Type 字段来告诉浏览器返回文件的类型。头部字段不仅用于解决不同类型文件传输的问题,也可以实现其他很多功能如缓存、认证信息等。

HTTP/1.0 并不是一个“标准”,只是一份参考文档,不具有实际的约束力。

HTTP/1.1

随着互联网的快速发展,HTTP/1.0也无法满足用户需求了,最根本的问题就是链接问题, HTTP/1.0 每进行一次通信,都需要经历建立连接传输数据断开连接三个阶段。当一个页面引用了较多的外部文件时,这个建立连接和断开连接的过程就会增加大量网络开销。

为了解决 HTTP/1.0 的问题,1999 年推出的 HTTP/1.1 有以下特点:

  • 长连接:引入了 TCP 连接复用,即一个 TCP 默认不关闭,可以被多个请求复用
  • 并发连接:对一个域名的请求允许分配多个长连接(缓解了长连接中的「队头阻塞」问题)
  • 引入管道机制(pipelining),一个 TCP 连接,可以同时发送多个请求。(响应的顺序必须和请求的顺序一致,因此不常用)
  • 增加了 PUT、DELETE、OPTIONS、PATCH 等新的方法
  • 新增了一些缓存的字段(If-Modified-Since, If-None-Match)
  • 请求头中引入了 range 字段,支持断点续传
  • 允许响应数据分块(chunked),利于传输大文件
  • 强制要求 Host 头,让互联网主机托管成为可能

HTTP管道机制(pipelining)

它指的是在一个TCP连接内,多个HTTP请求可以并行,客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能 够区分出每次请求的响应内容。

随着网络的发展,HTTP 1.1 还是暴露出一些局限性:

  1. 虽然加入 keep-alive 可以复用一部分连接,但域名分片等情况下仍然需要建立多个connection,耗费资源,给服务器带来性能压力。
  2. pipeling 只部分解决了队头阻塞( HOLB)。 HTTP 1.1 尝试使用 pipeling 来解决队头阻塞问题,即浏览器可以一次性发出多个请求(同个域名、同一条 TCP 链接)。 但 pipeling 要求返回是按序的,那么前一个请求如果很耗时(比如处理大图片),那么后面的请求即使服务器已经处理完,仍会等待前面的请求处理完才开始按序返回。
  3. 协议开销大,没有相应的压缩传输优化方案。 HTTP/1.1 在使用时,header 里携带的内容过大,在一定程度上增加了传输的成本,并且每次请求 header 基本不怎么变化,尤其在移动端增加用户流量。

HTTP/1.1 通过长连接减少了大量创建/断开连接造成的性能消耗,但是它的并发能力受到限制,表现在两个方面:

  • HTTP/1.1 中使用持久连接时,一个连接中同一时刻只能处理一个请求。当前的请求没有结束之前,其他的请求只能处于阻塞状态,这种情况被称为队头阻塞
  • 浏览器为了减轻服务器的压力,限制了同一个域名下的 HTTP 连接数,一般为 6 ~ 8 个。为了解决数量限制,出现了 域名分片 技术,其实就是资源分域,将资源放在不同域名下 (比如二级子域名下),这样就可以针对不同域名创建连接并请求,以一种讨巧的方式突破限制,但是滥用此技术也会造成很多问题,比如每个 TCP 连接本身需要经过 DNS 查询、三步握手、慢启动等,还占用额外的 CPU 和内存,对于服务器来说过多连接也容易造成网络拥挤、交通阻塞等。

SPDY:HTTP1.X的优化(改进版HTTP/1.1)

2012年google提出了SPDY的方案,优化了HTTP1.X的请求延迟,解决了HTTP1.X的安全性,具体如下:

  1. 降低延迟: 针对HTTP高延迟的问题,SPDY优雅的采取了多路复用(multiplexing)。多路复用通过多个请求stream共享一个tcp连接的方式,解决了HOL blocking的问题,降低了延迟同时提高了带宽的利用率。
  2. 请求优先级(request prioritization):多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。
  3. header压缩:前面提到HTTP1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。
  4. 基于HTTPS的加密协议传输:大大提高了传输数据的可靠性。
  5. 服务端推送(server push):可以让服务端主动把资源文件推送给客户端。当然客户端也有权利选择是否接收。

HTTP/2

2015 年正式发布的 HTTP/2 默认不再使用 ASCII 编码传输,而是改为二进制数据,来提升传输效率。

客户端在发送请求时会将每个请求的内容封装成不同的带有编号的二进制帧(Frame),然后将这些帧同时发送给服务端。服务端接收到数据之后,会将相同编号的帧合并为完整的请求信息。同样,服务端返回结果、客户端接收结果也遵循这个帧的拆分与组合的过程。

有了二进制分帧后,对于同一个域,客户端只需要与服务端建立一个连接即可完成通信需求,这种利用一个连接来发送多个请求的方式称为多路复用。每一条路都被称为一个stream(流)

特点:

  • 二进制协议: HTTP/1.1版本的头部信息是文本,数据部分可以是文本也可以是二进制。HTTP/2版本的头部和数据部分都是二进制,且统称为‘帧’
  • 多路复用: 废弃了 HTTP/1.1 中的管道,同一个TCP连接里面,客户端和服务器可以同时发送多个请求和多个响应,并且不用按照顺序来。由于服务器不用按顺序来处理响应,所以避免了“对头堵塞”的问题。
  • 头部信息压缩: 使用专用算法压缩头部,减少数据传输量,主要是通过服务端和客户端同时维护一张头部信息表,所有的头部信息在表里面都会有对应的记录,并且会有一个索引号,这样后面只需要发送索引号即可
  • 服务端主动推送: 允许服务器主动向客户推送数据
  • 数据流: 由于HTTP/2版本的数据包不是按照顺序发送的,同一个TCP连接里面相连的两个数据包可能是属于不同的响应,因此,必须要有一种方法来区分每一个数据包属于哪个响应。HTTP/2版本中,每个请求或者响应的所有数据包,称为一个数据流(stream),并且每一个数据流都有一个唯一的编号ID,请求数据流的编号ID为奇数,响应数据流的编号ID为偶数。每个数据包在发送的时候带上对应数据流的编号ID,这样服务器和客户端就能分区是属于哪一个数据流。最后,客户端还能指定数据流的优先级,优先级越高,服务器会越快做出响应。

缺点:

HTTP/2虽然解决了许多问题,但在TCP协议级别上仍然存在类似的队头问题,而TCP仍然是Web的构建基础。当 TCP 数据包在传输过程中丢失时,在服务器重新发送丢失的数据包之前,接收方无法确认传入的数据包。由于 TCP 在设计上不遵循 HTTP 之类的高级协议,因此单个丢失的数据包将阻塞所有进行中的 HTTP 请求的流,直到重新发送丢失的数据为止。这个问题在不可靠的连接上尤为突出,这在无处不在的移动设备时代并不罕见。

HTTP/3

HTTP/2 由于采用二进制分帧进行多路复用,通常只使用一个 TCP 连接进行传输,在丢包或网络中断的情况下后面的所有数据都被阻塞。

HTTP/2 的问题不能仅靠应用程序层来解决,因此协议的新迭代必须更新传输层。但是,创建新的传输层协议并非易事。传输协议需要硬件供应商的支持,并且需要大多数网络运营商的部署才能普及。

幸运的是还有另一种选择。UDP 协议与 TCP 一样得到广泛支持,但前者足够简单,可以作为在其之上运行的自定义协议的基础。UDP 数据包是一劳永逸的:没有握手、持久连接或错误校正。HTTP3 背后的主要思想是放弃 TCP,转而使用基于 UDP 的 QUIC (快速UDP互联网连接)协议。

与 HTTP2 在技术上允许未加密的通信不同,QUIC 严格要求加密后才能建立连接。此外,加密不仅适用于 HTTP 负载,还适用于流经连接的所有数据,从而避免了一大堆安全问题。建立持久连接、协商加密协议,甚至发送第一批数据都被合并到 QUIC 中的单个请求/响应周期中,从而大大减少了连接等待时间。如果客户端具有本地缓存的密码参数,则可以通过简化的握手重新建立与已知主机的连接。

为了解决传输级别的线头阻塞问题,通过 QUIC 连接传输的数据被分为一些流。流是持久性 QUIC 连接中短暂、独立的“子连接”。每个流都处理自己的错误纠正和传递保证,但使用连接全局压缩和加密属性。每个客户端发起的 HTTP 请求都在单独的流上运行,因此丢失数据包不会影响其他流/请求的数据传输。

各版本对比

协议版本

解决的核心问题

解决方式

0.9

HTML 文件传输

确立了客户端请求、服务端响应的通信流程

1.0

不同类型文件传输

设立头部字段

1.1

创建/断开 TCP 连接开销大

建立长连接进行复用

2

并发数有限

二进制分帧

3

TCP 丢包阻塞

采用 UDP 协议

SPDY

HTTP1.X的请求延迟

多路复用

HTTP的三次握手与四次挥手?♂?

一个完整的HTTP是包含请求与响应的,所以需要通过TCP来创建连接通道

一个TCP通道可以通过多个HTTP请求

一般来讲需要通过三次握手来确认连接过程,规避因为网络原因从而产生的资源消耗,从而创建TCP连接

三次握手

第一次握手: 客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

四次挥手

与建立连接的“三次握手”类似,断开一个TCP连接则需要“四次握手”。

第一次挥手: 主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。

第二次挥手: 被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。

第三次挥手: 被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。

第四次挥手: 主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。

HTTP/1.0与HTTP/1.1的区别

长连接

HTTP 1.1支持长连接(PersistentConnection)和请求的管道(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: Keep-Alive; HTTP1.0默认使用短连接,规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪 每个客户也不记录过去的请求。要建立长连接,可以在请求消息中包含Connection: Keep-Alive头域,如果服务器愿意维持这条连接,在响应消息中也会包含一个Connection: Keep-Alive的头域。

缓存处理

在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tagIf-Unmodified-Since,If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

  • Expires:浏览器会在指定过期时间内使用本地缓存,指明应该在什么时候认为文档已经过期,从而不再缓存它,时间为格林威治时间GMT。例如: Expires: Thu, 19 Nov 1981 08:52:00 GMT 
  • Last-Modified:请求对象最后一次的修改时间 用来判断缓存是否过期 通常由文件的时间信息产生
  • Date:生成消息的具体时间和日期,即当前的GMT时间。例如:Date: Sun, 17 Mar 2013 08:12:54 GMT
  • If-Modified-Since:客户端存取的该资源最后一次修改的时间,用来和服务器端的Last-Modified做比较
  • Set-Cookie: 用于把cookie 发送到客户端。例如: Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
  • Pragma:no-cache:客户端使用该头域说明请求资源不能从cache中获取,而必须回源获取。

带宽优化

HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。

错误通知的管理(状态码)

在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

Host头处理

在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

HTTP/2与SPDY的区别

  1. HTTP2.0 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS
  2. HTTP2.0 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DEFLATE

HTTP/1.1与HTTP/2的区别

  • 新的二进制格式(Binary Format),HTTP1.x解析是基于文本的,基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
  • 多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
  • header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
  • 服务端推送(server push),同SPDY一样,HTTP2.0也具有server push功能。

HTTP/2的多路复用和HTTP/1.X中的长连接复用的区别

  • HTTP/1.X 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
  • HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
  • HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;

HTTP/1.1与HTTP/2性能对比

官网提供了多种版本的对比测试有HTTP1.1与HTTP2的比较,还有服务器端推送(server-push)不同个数之间的比较:(由于网络延迟不同,测试结果或有差异)

可以看到分别使用HTTP/1.1和HTTP/2加载同一张由多张小图片组成的大图片:HTTP/1.1用了7.41s,而HTTP/2只用了1.47s。HTTP2比HTTP/1.1快了将近5倍。
因为为了加载这张大图,需要请求许多的小图,HTTP/1.1采用的是串行请求,所以速度要比采用并行请求的HTTP/2要慢上许多。

HTTP与HTTPS的区别

HTTPS

HTTPS是以安全为目标的 HTTP 通道,是 HTTP 的安全版。HTTPS 的安全基础是 SSL。SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。

SSL 协议可分为两层:

  • SSL 记录协议(SSL Record Protocol),它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
  • SSL 握手协议(SSL Handshake Protocol),它建立在 SSL 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

HTTPS的优点

  • 使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器。
  • HTTPS 协议是由SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 HTTP 协议安全,可防止数据在传输过程中不被窃取、修改,确保数据的完整性。
  • HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

HTTPS的缺点

  • HTTPS 协议握手阶段比较费时,会使页面的加载时间延长近。
  • HTTPS 连接缓存不如 HTTP 高效,会增加数据开销,甚至已有的安全措施也会因此而受到影响。
  • HTTPS 协议的安全是有范围的,在黑客攻击、拒绝服务攻击和服务器劫持等方面几乎起不到什么作用。
  • SSL 证书通常需要绑定 IP,不能在同一 IP 上绑定多个域名,IPv4 资源不可能支撑这个消耗。
  • 部署 HTTPS 后,因为 HTTPS 协议的工作要增加额外的计算资源消耗,例如 SSL 协议加密算法和 SSL 交互次数将占用一定的计算资源和服务器成本。
  • HTTPS 协议的加密范围也比较有限。最关键的,SSL 证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行。

与HTTP的区别

  • HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。
  • HTTP与HTTPS的连接方式不同,端口也不同,HTTP端口用的是80,HTTPS端口用的是443。
  • HTTP 的连接很简单,是无状态的。HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久地维持对方的任何信息。)
  • HTTPS协议需要申请证书,一般免费的证书很少。


作者:前端南玖

出处:https://www.cnblogs.com/songyao666/p/16065502.html