超文本传输协议(HTTP)是一个用于分布式、协作式和超媒体信息系统应用层协议。[1]HTTP是万维网数据通信的基础,万维网中的超文本文档包括一些指向其他资源的超链接,用户可以通过例如点击鼠标或者在网络浏览器中点击屏幕,轻松的访问这些资源。开发HTTP是为了促进超文本和万维网的发展。
HTTP的开发是由蒂姆·伯纳斯·李于1989年在欧洲核子研究中心所发起。HTTP的标准制定是互联网工程任务组(IETF)和万维网联盟(W3C)协调工作的成果。这些工作最终导致了一系列征求意见稿(RFC)的出版。HTTP/1.1的首个定义于1997年发表在RFC 2068中,该HTTP版本至今仍被广泛的使用。该版本在1999年被RFC 2616弃用,新的版本然后又于2014年被RFC 7230系列的RFC取代。
后来的版本,HTTP/2,于2015年被标准化。HTTP/3是基于HTTP/2的继任者(互联网草稿)[2][3],并且,通过一个必须有TLS 1.2或者更新版本的应用层协议协商(ALPN)扩展,现在得到了主要网络服务器和浏览器在传输层安全性协议(TLS)的支持[4]。[5]
HTTP / 3是HTTP / 2 的继承者,使用UDP代替TCP作为基础传输协议。像HTTP / 2一样,它不会淘汰该协议的先前主要版本。在2019年9月26日,Cloudflare,Google Chrome和Mozilla Firefox中添加了HTTP / 3支持。
HTTP在客户端-服务器计算模型中用作请求-响应协议。例如,客户端可以是一个网络浏览器,服务器可能是一个运行在计算机上,作为一个网站主机的应用程序。客户端向服务器提交一个HTTP请求消息。服务器提供诸如HTML文件和其他内容的资源,或者代表客户端执行其他功能,向客户端返回一个响应信息。这一响应包含关于请求的完成状态信息,也可能在其消息正文中包含请求的内容。
网络浏览器是用户代理(UA)的一个实例。其他类型的用户代理包括搜索提供商(网络爬虫),语音浏览器,移动应用和访问、使用或显示网络内容的其他软件所使用的索引软件。
HTTP旨在允许中间网络元素改进或支持客户端和服务器之间的通信。高流量网站通常受益于代表上游服务器提供内容的web缓存服务器以缩短响应时间。网络浏览器缓存先前访问的网络资源,并尽可能重用它们以减少网络流量。通过与外部服务器中继消息,专用网边界的HTTP代理服务系统可以在没有全局可路由地址的情况下促进客户端的通信。
HTTP是一个在互联网协议套件框架内设计的协议的应用层协议。它的定义假定存在一个潜在的和可靠的传输层协议,[6]并且传输控制协议(TCP)是常被用到的。但是,可以修改HTTP来使用例如用户数据报协议(UDP)不可靠的协议,比如在HTTPU和简单服务发现协议(SSDP)中。
使用统一资源标识符(URI)方案http和https,HTTP资源由统一资源定位符(URLs)在网络被识别与定位。例如,包括所有可选组件:
userinfo
┌───────┴───────┐ ┌────┴────────┐ ┌┴┐
http://john.doe:password@www.example.com:123/forum/questions/?tag=networking&order=newest#top
└─┬─┘ └───────────┬────────────────────────┘└─┬─────────────┘└────────┬──────────────────┘└┬─┘
authority path
HTTP/1.1是对初始HTTP(HTTP/1.0)的修订。在HTTP/1.0中,对于每个资源请求都是建立到同一个服务器的一个单独连接。HTTP/1.1可以在获得页面后,多次重复使用一个连接来下载图像,脚本,样式表,等等。因此,当建立TCP连接会带来相当大的开销时,HTTP/1.1通信经历的延迟却越短。
URI被编码为文件中的,以便形成相互链接文件。
超文本这一术语是由泰德·纳尔逊在1965年Xanadu项目中提出的。这又受到了万尼瓦尔·布什20世纪30年代关于基于缩微胶片的信息检索和管理系统"memex",该系统在他1945年的文章"As We May Think"中有所描述。蒂姆·伯纳斯·李和他在欧洲核子研究中心的团队被认为发明了最初的HTTP,以及HTML和与网页服务器和基于文本的网页浏览器相关的技术。伯纳斯-李在1989年首次提出了“WorldWideWeb”项目——现在被称为万维网。该协议的第一个版本只有一种方法,即GET,它会向服务器请求一个页面。[7]服务器的响应总是一个HTML页面。[8]
第一个记录在案的HTTP版本是HTTP V0.9(1991年)。Dave Raggett于1995年领导了HTTP工作组(HTTP WG),希望通过扩展操作、扩展协商、更丰富的元信息来扩展协议,并与通过添加额外方法和头字段。[9][10]RFC 1945于1996年正式推出并发布了HTTP 1.0版。
该工作组计划在1995年12月发布新的标准[11]并且对基于当时正处于开发中的RFC 2068(称为HTTP-NG)所开发的预先标准化的HTTP/1.1的支持在1996年初被主流浏览器开发者迅速采用。到那年3月,在Arena浏览器,[12]网景导航者2.0,[12]网景导航者黄金版2.01,[12]Mosaic浏览器2.7,Lynx浏览器2.5,和Internet Explorer 2.0中,预先标准化的HTTP/1.1已得到支持。终端用户很快地适应了新的浏览器。1996年3月,一家网络托管公司报告说,互联网上使用的浏览器中有40%以上符合HTTP/1.1标准。这家网络托管公司报告说,到1996年6月,所有访问他们服务器的浏览器中有65%符合HTTP/1.1标准。[13]RFC 2068定义的HTTP/1.1标准于1997年1月正式发行。对HTTP/1.1标准的改进和更新发布于1999年6月RFC 2616中。
2007年HTTPbis Working Group成立了,该组织的部分工作是为了修订和阐述HTTP/1.1规范。2014年6月,工作组发布了更新后的六部分规范废弃RFC 2616以下内容:
HTTP/2发表于2015年5月RFC 7540中。
年份 | HTTP 版本 |
---|---|
1991 | 0.9 |
1996 | 1.0 |
1997 | 1.1 |
2015 | 2.0 |
2018 | 3.0 |
HTTP会话是一系列网络请求-响应事务。一个HTTP客户端通过建立一个连接到服务器上的特定端口(通常是端口80,偶尔是端口8080),来启动请求。监听该端口的一个HTTP服务器等待客户端的请求消息。收到请求后,服务器会返回一个状态行,如“HTTP/1.1 200 OK”,以及它自己的消息。该消息的正文通常是请求的资源,尽管也可能返回错误消息或其他信息。[1]
在HTTP/0.9和1.0中,连接在单个请求-响应之后关闭。在HTTP/1.1中引入了一种保持活跃的机制,在这种机制中,一个连接可以被多个请求重用。这样的持久连接明显地减少请求延迟,这是因为客户端在发送第一个请求后不需要重新协商TCP 3-Way握手连接。另一个积极的副作用是,一般来说,由于TCP的慢启动-机制,连接会随着时间而变得更快。
该协议的1.1版还对HTTP/1.0进行了带宽优化改进。例如,HTTP/1.1引入了分块传输编码以允许对持久连接上的内容进行流式传输而不是缓冲。HTTP管线化技术进一步减少延迟时间,允许客户端在等待每个响应之前发送多个请求。对该协议的另一个补充是Byte serving,其中服务器仅传输客户端明确请求的那部分的资源。
HTTP是一个无状态协议。无状态协议不需要HTTP服务器在多个请求期间保留每个用户的信息或状态。然而,有些网络应用程序使用例如HTTPcookie或网页窗体中的隐藏变量实现状态或服务器端会话.
客户端和服务器通过发送纯文本(ASCII)消息进行通信。客户端向服务器发送请求,服务器发送响应。
请求消息包括以下内容:
/images/logo.png
。)请求行和其他标题字段必须以<CR><LF>(即回车字符后加上换行字符)结尾。空行必须仅包含<CR><LF>,不包含其他空白内容。[15]在HTTP/1.1协议中,所有除了Host的字段是可选的。
服务器接受只包含路径名的请求行,以便保持与仅支持RFC 1945中的HTTP/1.0之前规范HTTP客户端的兼容性。[16]
请求方法
HTTP定义方法(有时也称为verbs,但规范中没有提到verbs,也没提到OPTIONS或HEAD一个verbs)来指示要在所识别的资源上期望执行的动作。该资源代表的内容,是预先存在的数据还是动态生成的数据,都取决于服务器的实现。通常,资源对应于驻留在服务器上的文件或可执行文件的输出。HTTP/1.0规范[17]定义了GET、HEAD和POST方法以及HTTP/1.1规范[18]添加了五种新方法:OPTIONS、PUT、DELETE、TRACE和CONNECT。通过在这些文档中被指定,它们的含义是众所周知的,并且可以互相依赖的。任何客户端都可以使用任何方法,并且服务器可以配置为支持任何方法组合。如果网络中间层不知道某个方法,它将被视为不安全的非幂等的方法。对可以定义的方法数量没有限制,这允许在不破坏现有基础架构的情况下指定未来的方法。例如,WebDAV定义了7种新方法,以及RFC 5789指定了PATCH方法。
方法名区分大小写[19][20]。这与不区分大小写的HTTP头字段名称形成对比[21]。
所有通用的HTTP服务器都需要实现至少GET和HEAD方法,规范认为所有其他方法都是可选的。[29]
安全方法
按照惯例,其中一些方法(例如GET、HEAD、OPTIONS和TRACE)被定义为是安全的,这意味着它们仅用于信息检索,不应改变服务器的状态。换句话说,他们不应该有副作用,除了了一些相对无害的影响,例如记录日志,web缓存,横幅广告或者增加一个网络计数器。因此,在不考虑应用程序状态的情况下发出任意GET请求应该被认为是安全的。然而,标准没有规定这一点,并且明确承认它不能得到保证。
相比之下,POST、PUT、DELETE和PATCH等方法旨在用于可能对服务器造成副作用或外部副作用的操作,例如金融交易或传输电子邮件。因此,这种方法通常不被网络机器人或者网络爬虫使用;有些不符合规则的网络机器人或爬虫倾向于在不考虑背景或后果是提出请求。
尽管GET请求的安全性得到了肯定,但是,实际上,服务器对请求的处理在技术上没有任何限制。因此,粗心或故意的程序会对服务器造成不小的改变。这是不被鼓励的,这是因为它会给网络缓存,搜索引擎和其他自动化代理造成问题,这些请求可能会对服务器进行意外更改。例如,网站可能允许通过以下URL删除资源http://example.com/article/1234/delete,如果获取方式是随意的话,甚至仅仅使用GET请求,也会删除该文章。[30]
这种情况的一个实际的例子是在短命的谷歌网际加速器beta,它预取用户正在查看的页面上的任意URLs,导致全体地记录被自动更改或删除。由于广泛的批评,该测试版在首次发布后仅几周就暂停了。[31][30]
幂等方法和网络应用
方法PUT和DELETE被定义为是幂等的,这意味着多个相同的请求应该具有与单个请求相同的效果。方法GET、HEAD、OPTIONS和TRACE,被规定为安全的,也应该是幂等的,这是因为HTTP是一个无状态协议。[1]
相反,POST方法不一定是幂等的,因此多次发送相同的POST请求可能会进一步影响状态或导致进一步的副作用(例如金融交易)。在某些情况下,这可能是可取的,但是在其他情况下,这可能是由事故造成的,例如当用户没有意识到他们的动作将导致发送另一个请求,或者他们没有收到关于他们的第一个请求成功的足够的反馈时。虽然网络浏览器可能会显示警报对话框以警告用户:在某些情况下,重新加载页面可能会重新提交POST请求,但是通常由网络应用程序来处理POST检请求不应提交一次以上的情况。
请注意,一个方法是否幂等并不由协议或网络服务器强制执行。编写一个GET或其他请求触发数据库插入或其他非幂等操作网络应用程序是完全可能的,但是,如果用户代理假定重复相同的请求是安全的,忽略此建议可能会导致不良后果。
安全
TRACE方法可以用作被称为跨站点跟踪攻击的一部分;因此,常见的安全建议是在服务器配置中禁用它。[32]Microsoft IIS支持专有的“TRACK”方法,其行为与TRACE类似,同样建议禁用。[32]
一览表
HTTP 方法 | RFC版本 | 是否有请求主体 | 是否有响应主体 | 是否安全 | 是否幂等 | 是否可缓存 |
---|---|---|---|---|---|---|
GET | RFC 7231 | 可选 | 是 | 是 | 是 | 是 |
HEAD | RFC 7231 | 可选 | 否 | 是 | 是 | 是 |
POST | RFC 7231 | 是 | 是 | 否 | 否 | 是 |
PUT | RFC 7231 | 是 | 是 | 否 | 是 | 否 |
DELETE | RFC 7231 | 可选 | 是 | 否 | 是 | 否 |
CONNECT | RFC 7231 | 可选 | 是 | 否 | 否 | 否 |
OPTIONS | RFC 7231 | 可选 | 是 | 是 | 是 | 否 |
TRACE | RFC 7231 | 否 | 是 | 是 | 是 | 否 |
PATCH | RFC 5789 | 是 | 是 | 否 | 否 | 否 |
响应消息包括以下内容:
状态行和其他回应字段都必须以<CR><LF>结尾。空行必须仅包含<CR><LF>,不包含其他空白内容。[15]对于<CR><LF>的严格要求在报文主体中有所宽松,以便一致地使用其他系统换行符,例如<CR>或<LF>。[33]
状态代码
在HTTP/1.0和此后的版本中,HTTP响应的第一行称为状态行并且包括一个数字状态代码(例如”404”)和文本消息短语(如“未找到”)。用户代理处理响应的方法主要取决于状态代码,其次取决于其他响应字段。可以使用自定义状态代码,因为如果用户代理遇到它无法识别的代码,它可以使用状态代码的第一个数字来确定响应的一般类别。[34]
标准消息短语仅是建议,可以由网络开发者自行决定用其他“方言”代替他们。如果状态代码表明有问题,用户代理可能会显示消息短语以提供关于问题性质的进一步信息。该标准还允许用户代理尝试解释消息短语,尽管这可能是不明智的,因为标准明确规定状态代码是机器可读的而消息短语是人类可读的。为了更好地解释客户机和服务器之间的请求和响应,HTTP状态代码主要分为五组,命名为:
1XX
2XX
3XX
4XX
5XX
下面是一个HTTP客户端与一个运行在www.example.com,端口80的HTTP服务器会话示例。如前所述,所有数据都是以纯文本形式发送的(美国信息交换标准码)编码,每行的末尾以双字节<CR><LF>('\r\n')结束。
GET / HTTP/1.1
Host: www.example.com
客户端请求(在这种情况下由请求行和一个标题字段组成)后面跟着一个空行,以便请求以一个双换行符结束,每个换行符都是回车符接下来是一个换行符。“主机”字段区分共享同一ip地址各种DNS名称,允许基于名称虚拟主机。虽然在HTTP/1.0中是可选的,但在HTTP/1.1中是强制性的。“/”表示/index.html(如果有的话)。)
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close
<html>
<head>
<title>An Example Page</title>
</head>
<body>
<p>Hello World, this is a very simple HTML document.</p>
</body>
</html>
ETag(实体标签)标头字段用于确定所请求资源的缓存版本是否与服务器上资源的当前版本相同。Content-Type指定HTTP消息传输的数据的互联网媒体类型,而Content-Length表示其长度(单位:字节)。HTTP/1.1网络服务器通过设置字段Accept-Range:bytes发布其对文档特定字节范围请求的响应能力。这一设计的意义在于,如果客户端只需要由服务器发送的资源某些部分[39],称为Byte serving。当Connection:close发送时,表示web服务器将在此次传输响应后立即关闭TCP链接。
大多数表头行是可选的。当缺少Content-Length时,长度是由其他方式确定。分块传输编码使用一个大小为0的块来标记内容的结尾。没有Content-Length的身份编码会在套接字关闭之前读取内容。
像gzip这样的内容编码可用于压缩传输的数据。
Gopher协议是20世纪90年代早期被超文本传输协议取代的内容传输协议。SPDY协议是谷歌开发的HTTP替代方案,它被新的HTTP协议HTTP/2取代。
^Fielding, Roy T.; Gettys, James; Mogul, Jeffrey C.; Nielsen, Henrik Frystyk; Masinter, Larry; Leach, Paul J.; Berners-Lee, Tim. Hypertext Transfer Protocol – HTTP/1.1. IETF. June 1999. RFC 2616..
^Bishop, Mike. "Hypertext Transfer Protocol (HTTP) over QUIC". tools.ietf.org (in 英语). Retrieved 2018-11-19..
^Cimpanu, Catalin. "HTTP-over-QUIC to be renamed HTTP/3 | ZDNet". ZDNet (in 英语). Retrieved 2018-11-19..
^"Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension". IETF. July 2014. RFC 7301..
^Belshe, M.; Peon, R.; Thomson, M. "Hypertext Transfer Protocol Version 2, Use of TLS Features". Retrieved 2015-02-10..
^Overall Operation. RFC 2616: p. 12. sec. 1.4. RFC 2616..
^Berners-Lee, Tim. "HyperText Transfer Protocol". World Wide Web Consortium. Retrieved 31 August 2010..
^Tim Berners-Lee. "The Original HTTP as defined in 1991". World Wide Web Consortium. Retrieved 24 July 2010..
^Raggett, Dave. "Dave Raggett's Bio". World Wide Web Consortium. Retrieved 11 June 2010..
^Raggett, Dave; Berners-Lee, Tim. "Hypertext Transfer Protocol Working Group". World Wide Web Consortium. Retrieved 29 September 2010..
^Raggett, Dave. "HTTP WG Plans". World Wide Web Consortium. Retrieved 29 September 2010..
^Simon Spero. "Progress on HTTP-NG". World Wide Web Consortium. Retrieved 11 June 2010..
^"HTTP/1.1". Webcom.com Glossary entry. Archived from the original on 2001-11-21. Retrieved 2009-05-29..
^Fielding, Roy T.; Reschke, Julian F.. Hypertext Transfer Protocol (HTTP/1.1): Authentication. IETF. June 2014. RFC 7235..
^HTTP Message. RFC 2616: p. 31. sec. 4. RFC 2616..
^"Apache Week. HTTP/1.1". 090502 apacheweek.com.
^Berners-Lee, Tim; Fielding, Roy T.; Nielsen, Henrik Frystyk. Method Definitions. Hypertext Transfer Protocol – HTTP/1.0. IETF: pp. 30–32. sec. 8. RFC 1945..
^Method Definitions. RFC 2616: pp. 51–57. sec. 9. RFC 2616..
^RFC-7210 section 3.1.1.
^RFC-7231 section 4.1.
^RFC-7230 section 3.2.
^Jacobs, Ian (2004). "URIs, Addressability, and the use of HTTP GET and POST". Technical Architecture Group finding. W3C. Retrieved 26 September 2010..
^POST. RFC 2616: p. 54. sec. 9.5. RFC 2616..
^PUT. RFC 2616: p. 55. sec. 9.6. RFC 2616..
^CONNECT. Hypertext Transfer Protocol – HTTP/1.1. IETF. June 1999: p. 57. sec. 9.9 [23 February 2014]. RFC 2616..
^Khare, Rohit; Lawrence, Scott. Upgrading to TLS Within HTTP/1.1. IETF. May 2000. RFC 2817..
^"Vulnerability Note VU#150227: HTTP proxy default configurations allow arbitrary TCP connections". US-CERT. 2002-05-17. Retrieved 2007-05-10..
^Dusseault, Lisa; Snell, James M.. PATCH Method for HTTP. IETF. March 2010. RFC 5789..
^Method. RFC 2616: p. 36. sec. 5.1.1. RFC 2616..
^Ediger, Brad (2007-12-21). Advanced Rails: Building Industrial-Strength Web Apps in Record Time. O'Reilly Media, Inc. p. 188. ISBN 978-0596519728. A common mistake is to use GET for an action that updates a resource. [...] This problem came into the Rails public eye in 2005, when the Google Web Accelerator was released..
^Cantrell, Christian (2005-06-01). "What Have We Learned From the Google Web Accelerator?". Adobe Blogs. Adobe. Archived from the original on 2017-08-19..
^"Cross Site Tracing". OWASP. Retrieved 2016-06-22..
^Canonicalization and Text Defaults. RFC 2616: sec. 3.7.1. RFC 2616..
^Status-Line. RFC 2616: p. 39. sec. 6.1. RFC 2616..
^Canavan, John (2001). Fundamentals of Networking Security. Norwood, MA: Artech House. pp. 82–83. ISBN 9781580531764..
^Zalewski, Michal. "Browser Security Handbook". Retrieved 30 April 2015..
^"Chromium Issue 4527: implement RFC 2817: Upgrading to TLS Within HTTP/1.1". Retrieved 30 April 2015..
^"Mozilla Bug 276813 – [RFE] Support RFC 2817 / TLS Upgrade for HTTP 1.1". Retrieved 30 April 2015..
^Luotonen, Ari; Franks, John. Byte Range Retrieval Extension to HTTP. IETF. February 22, 1996. I-D draft-ietf-http-range-retrieval-00..
暂无