1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
---
title: HTTP消息
slug: Web/HTTP/Messages
tags:
- 指南 HTTP
translation_of: Web/HTTP/Messages
---
<div>{{HTTPSidebar}}</div>
<p class="summary">HTTP消息是服务器和客户端之间交换数据的方式。有两种类型的消息︰ 请求(requests)--由客户端发送用来触发一个服务器上的动作;响应(responses)--来自服务器的应答。</p>
<p>HTTP消息由采用ASCII编码的多行文本构成。在HTTP/1.1及早期版本中,这些消息通过连接公开地发送。在HTTP/2中,为了优化和性能方面的改进,曾经可人工阅读的消息被分到多个HTTP帧中。</p>
<p>Web 开发人员或网站管理员,很少自己手工创建这些原始的HTTP消息︰ 由软件、浏览器、 代理或服务器完成。他们通过配置文件(用于代理服务器或服务器),API (用于浏览器)或其他接口提供HTTP消息。</p>
<p><img alt="From a user-, script-, or server- generated event, an HTTP/1.x msg is generated, and if HTTP/2 is in use, it is binary framed into an HTTP/2 stream, then sent." src="https://mdn.mozillademos.org/files/13825/HTTPMsg2.png" style="height: 538px; width: 1174px;"></p>
<p>HTTP/2二进制框架机制被设计为不需要改动任何API或配置文件即可应用︰ 它大体上对用户是透明的。</p>
<div class="textArea" id="destText" style="direction: ltr;">
<div><span id="ouHighlight__0_3TO0_3">HTTP</span><span id="noHighlight_0.5187132851681917"> </span><span id="ouHighlight__5_12TO5_6">请求</span><span id="ouHighlight__15_17TO7_7">和</span><span id="ouHighlight__19_27TO8_9">响应</span><span id="ouHighlight__28_28TO10_10">具有</span><span id="ouHighlight__36_42TO13_14">相似</span><span id="noHighlight_0.6112710687035254">的</span><span id="ouHighlight__44_52TO16_17">结构,</span><span id="ouHighlight__54_56TO18_18">由以下部分</span><span id="ouHighlight__62_69TO19_20">组成</span><span id="ouHighlight__73_73TO21_21">︰</span></div>
</div>
<ol>
<li>一行<span class="highlighted" id="ouHighlight__4_13TO0_2">起</span>始行用于描述要执行的请求,或者是对应的状态,成功或失败。这个<span class="highlighted" id="ouHighlight__4_13TO0_2">起</span>始行总是单行的。</li>
<li>一个可选的HTTP头集合指明请求或描述消息正文。</li>
<li>一个空行指示所有关于请求的元数据已经发送完毕。</li>
<li>一个可选的包含请求相关数据的正文 (比如HTML表单内容), 或者响应相关的文档。 正文的大小有<span class="highlighted" id="ouHighlight__4_13TO0_2">起</span>始行的HTTP头来指定。</li>
</ol>
<p><span class="highlighted" id="ouHighlight__4_13TO0_2">起始行</span><span id="ouHighlight__15_17TO3_3">和</span><span id="noHighlight_0.24094207099483878"> </span><span id="noHighlight_0.20506469395890603"> </span><span id="ouHighlight__39_42TO14_17">HTTP</span><span id="noHighlight_0.7326949190272041"> </span><span id="ouHighlight__44_50TO19_20">消息中的</span><span id="ouHighlight__19_22TO5_8">HTTP</span><span id="noHighlight_0.8511727000124978"> </span><span id="ouHighlight__24_30TO10_11">头</span><span id="ouHighlight__52_73TO21_22">统称</span><span id="ouHighlight__75_76TO23_23">为</span><span id="ouHighlight__94_101TO27_28">请求头</span><span id="ouHighlight__102_102TO29_29">,</span><span id="ouHighlight__104_110TO30_30">而</span><span id="ouHighlight__112_114TO31_31">其</span><span id="ouHighlight__116_122TO32_35">有效负载</span><span id="ouHighlight__124_125TO36_36">被</span><span id="ouHighlight__127_134TO37_38">称为</span><span id="ouHighlight__140_143TO39_40">消息正文</span><span id="noHighlight_0.0840453271452073">。</span></p>
<p><img alt="Requests and responses share a common structure in HTTP" src="https://mdn.mozillademos.org/files/13827/HTTPMsgStructure2.png" style="height: 368px; width: 1239px;"></p>
<h2 id="HTTP_请求">HTTP 请求</h2>
<h3 id="起始行"><span class="highlighted" id="ouHighlight__4_13TO0_2">起始行</span></h3>
<p>HTTP请求是由客户端发出的消息,用来使服务器执行动作。<em>起始行 (start-line) </em>包含三个元素:</p>
<ol>
<li>一个 <em><a href="/en-US/docs/Web/HTTP/Methods">HTTP 方法</a></em>,一个动词 (像 {{HTTPMethod("GET")}}, {{HTTPMethod("PUT")}} 或者 {{HTTPMethod("POST")}}) 或者一个名词 (像 {{HTTPMethod("HEAD")}} 或者 {{HTTPMethod("OPTIONS")}}), 描述要执行的动作. 例如, <code>GET</code> 表示要获取资源,<code>POST</code> 表示向服务器推送数据 (创建或修改资源, 或者产生要返回的临时文件)。</li>
<li><em>请求目标 (request target),</em>通常是一个 {{glossary("URL")}},或者是协议、端口和域名的绝对路径,通常以请求的环境为特征。请求的格式因不同的 HTTP 方法而异。它可以是:
<ul>
<li>一个绝对路径,末尾跟上一个 ' ? ' 和查询字符串。这是最常见的形式,称为 <em>原始形式 (origin form)</em>,被 GET,POST,HEAD 和 OPTIONS 方法所使用。<br>
<code>POST / HTTP/1.1<br>
GET /background.png HTTP/1.0<br>
HEAD /test.html?query=alibaba HTTP/1.1<br>
OPTIONS /anypage.html HTTP/1.0</code></li>
<li>一个完整的URL,被称为 <em>绝对形式 (absolute form)</em>,主要在使用 <code>GET</code> 方法连接到代理时使用。<br>
<code>GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1</code></li>
<li>由域名和可选端口(以<code>':'</code>为前缀)组成的 URL 的 authority component,称为 <em>authority form</em>。 仅在使用 <code>CONNECT</code> 建立 HTTP 隧道时才使用。<br>
<code>CONNECT developer.mozilla.org:80 HTTP/1.1</code></li>
<li><em>星号形式 (asterisk form)</em>,一个简单的星号(<code>'*'</code>),配合 <code>OPTIONS</code> 方法使用,代表整个服务器。<br>
<code>OPTIONS * HTTP/1.1</code></li>
</ul>
</li>
<li><em>HTTP 版本 (HTTP version</em>)<em>,</em>定义了剩余报文的结构,作为对期望的响应版本的指示符。</li>
</ol>
<h3 id="Headers">Headers</h3>
<p>来自请求的 <a href="/en-US/docs/Web/HTTP/Headers">HTTP headers</a> 遵循和 HTTP header 相同的基本结构:不区分大小写的字符串,紧跟着的冒号 <code>(':')</code> 和一个结构取决于 header 的值。 整个 header(包括值)由一行组成,这一行可以相当长。</p>
<p>有许多请求头可用,它们可以分为几组:</p>
<ul>
<li><em>General headers,</em>例如 {{HTTPHeader("Via")}},适用于整个报文。</li>
<li><em>Request headers,</em>例如<em> </em>{{HTTPHeader("User-Agent")}},{{HTTPHeader("Accept-Type")}},通过进一步的定义(例如 {{HTTPHeader("Accept-Language")}}),或者给定上下文(例如 {{HTTPHeader("Referer")}}),或者进行有条件的限制 (例如 {{HTTPHeader("If-None")}}) 来修改请求。</li>
<li><em>Entity headers,</em>例如 {{HTTPHeader("Content-Length")}},适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。</li>
</ul>
<p><img alt="Example of headers in an HTTP request" src="https://mdn.mozillademos.org/files/13821/HTTP_Request_Headers2.png" style="height: 280px; width: 872px;"></p>
<h3 id="Body">Body</h3>
<p>请求的最后一部分是它的 body。不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。</p>
<p>Body 大致可分为两类:</p>
<ul>
<li>Single-resource bodies,由一个单文件组成。该类型 body 由两个 header 定义: {{HTTPHeader("Content-Type")}} 和 {{HTTPHeader("Content-Length")}}.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#multipartform-data">Multiple-resource bodies</a>,由多部分 body 组成,每一部分包含不同的信息位。通常是和 <a href="/en-US/docs/Web/Guide/HTML/Forms">HTML Forms</a> 连系在一起。</li>
</ul>
<h2 id="HTTP_响应">HTTP 响应</h2>
<h3 id="状态行">状态行</h3>
<p>HTTP 响应的起始行被称作 <em>状态行</em> <em>(status line)</em>,包含以下信息:</p>
<ol>
<li><em>协议版本</em>,通常为 <code>HTTP/1.1。</code></li>
<li><em>状态码 (</em><em>status code)</em>,表明请求是成功或失败。常见的状态码是 {{HTTPStatus("200")}},{{HTTPStatus("404")}},或 {{HTTPStatus("302")}}。</li>
<li><em>状态文本 (status text)</em>。一个简短的,纯粹的信息,通过状态码的文本描述,帮助人们理解该 HTTP 消息。</li>
</ol>
<p>一个典型的状态行看起来像这样:<code>HTTP/1.1 404 Not Found</code>。</p>
<h3 id="Headers_2">Headers</h3>
<p>响应的 <a href="/en-US/docs/Web/HTTP/Headers">HTTP headers</a> 遵循和任何其它 header 相同的结构:不区分大小写的字符串,紧跟着的冒号 (<code>':'</code>) 和一个结构取决于 header 类型的值。 整个 header(包括其值)表现为单行形式。</p>
<p>有许多响应头可用,这些响应头可以分为几组:</p>
<ul>
<li><em>General headers,</em>例如 {{HTTPHeader("Via")}},适用于整个报文。</li>
<li><em>Response headers,</em>例如 {{HTTPHeader("Vary")}} 和 {{HTTPHeader("Accept-Ranges")}},提供其它不符合状态行的关于服务器的信息。</li>
<li><em>Entity headers</em>,例如 {{HTTPHeader("Content-Length")}},适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。</li>
</ul>
<p><img alt="Example of headers in an HTTP response" src="https://mdn.mozillademos.org/files/13823/HTTP_Response_Headers2.png" style="height: 344px; width: 805px;"></p>
<h3 id="Body_2">Body</h3>
<p>响应的最后一部分是 body。不是所有的响应都有 body:具有状态码 (如 {{HTTPStatus("201")}} 或 {{HTTPStatus("204")}}) 的响应,通常不会有 body。</p>
<p>Body 大致可分为三类:</p>
<ul>
<li>Single-resource bodies,由<strong>已知</strong>长度的单个文件组成。该类型 body 由两个 header 定义:{{HTTPHeader("Content-Type")}} 和 {{HTTPHeader("Content-Length")}}。</li>
<li>Single-resource bodies,由<strong>未知</strong>长度的单个文件组成,通过将 {{HTTPHeader("Transfer-Encoding")}} 设置为 <code>chunked </code>来使用 chunks 编码。</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#multipartform-data">Multiple-resource bodies</a>,由多部分 body 组成,每部分包含不同的信息段。但这是比较少见的。</li>
</ul>
<h2 id="HTTP2_帧">HTTP/2 帧</h2>
<p>HTTP/1.x 报文有一些性能上的缺点:</p>
<ul>
<li>Header 不像 body,它不会被压缩。</li>
<li>两个报文之间的 header 通常非常相似,但它们仍然在连接中重复传输。</li>
<li>无法复用。当在同一个服务器打开几个连接时:TCP 热连接比冷连接更加有效。</li>
</ul>
<p>HTTP/2 引入了一个额外的步骤:它将 HTTP/1.x 消息分成帧并嵌入到流 (stream) 中。数据帧和报头帧分离,这将允许报头压缩。将多个流组合,这是一个被称为 <em>多路复用 (multiplexing) </em>的过程,它允许更有效的底层 TCP 连接。</p>
<p><img alt="HTTP/2 modify the HTTP message to divide them in frames (part of a single stream), allowing for more optimization." src="https://mdn.mozillademos.org/files/13819/Binary_framing2.png" style="height: 735px; width: 810px;"></p>
<p>HTTP 帧现在对 Web 开发人员是透明的。在 HTTP/2 中,这是一个在 HTTP/1.1 和底层传输协议之间附加的步骤。Web 开发人员不需要在其使用的 API 中做任何更改来利用 HTTP 帧;当浏览器和服务器都可用时,HTTP/2 将被打开并使用。</p>
<h2 id="结论">结论</h2>
<p>HTTP 报文是使用 HTTP 的关键;它们的结构简单,并且具有高可扩展性。HTTP/2 帧机制是在 HTTP/1.x 语法和底层传输协议之间增加了一个新的中间层,而没有从根本上修改它,即它是建立在经过验证的机制之上。</p>
|