典型的 HTTP 会话
在像 HTTP 这样的客户端-服务器协议中,会话包含三个阶段
- 客户端建立 TCP 连接(如果传输层不是 TCP,则建立相应的连接)。
- 客户端发送其请求,并等待答案。
- 服务器处理请求,发送回其答案,提供状态码和适当的数据。
从 HTTP/1.1 开始,连接在完成第三阶段后不再关闭,并且客户端现在被授予进一步的请求:这意味着第二和第三阶段现在可以执行任意次数。
建立连接
在客户端-服务器协议中,是客户端建立连接。在 HTTP 中打开连接意味着在底层传输层(通常是 TCP)中启动连接。
对于计算机上的 HTTP 服务器,TCP 默认端口是 80 端口。也可以使用其他端口,例如 8000 或 8080。要获取的页面的 URL 包含域名和端口号,但如果端口号为 80,则可以省略端口号。有关更多详细信息,请参阅 URL 参考。
注意:客户端-服务器模型不允许服务器在没有显式请求的情况下向客户端发送数据。但是,各种 Web API 启用了这种用例,包括 推送 API、服务器发送事件 和 WebSocket API。
发送客户端请求
连接建立后,用户代理可以发送请求(用户代理通常是 Web 浏览器,但也可能是其他任何东西,例如爬虫)。客户端请求由文本指令组成,这些指令由 CRLF(回车符,后跟换行符)分隔,分为三个块
- 第一行包含请求方法及其参数
- 文档的路径,作为不带协议或域名名的绝对 URL
- HTTP 协议版本
- 后续行表示 HTTP 标头,它向服务器提供有关哪种数据类型合适的信息(例如,语言、MIME 类型)或其他更改其行为的数据(例如,如果已缓存,则不发送答案)。这些 HTTP 标头形成一个块,该块以空行结束。
- 最后一个块是可选数据块,它可能包含主要由 POST 方法使用的其他数据。
示例请求
获取 developer.mozilla.org 的根页面(https://mdn.org.cn/
),并告诉服务器用户代理如果可能,希望以法语获取页面
GET / HTTP/1.1
Host: developer.mozilla.org
Accept-Language: fr
观察最后的空行,它将数据块与标头块隔开。由于 HTTP 标头中没有提供 Content-Length
,因此此数据块显示为空,标记标头的结束,允许服务器在收到此空行时立即处理请求。
例如,发送表单的结果
POST /contact_form.php HTTP/1.1
Host: developer.mozilla.org
Content-Length: 64
Content-Type: application/x-www-form-urlencoded
name=Joe%20User&request=Send%20me%20one%20of%20your%20catalogue
请求方法
服务器响应结构
连接的代理发送其请求后,Web 服务器会处理它,并最终返回响应。类似于客户端请求,服务器响应由文本指令组成,这些指令由 CRLF 分隔,但分为三个块
- 第一行(状态行)包含对使用的 HTTP 版本的确认,后跟响应状态码(及其在人类可读文本中的简要含义)。
- 后续行表示特定的 HTTP 标头,它向客户端提供有关发送数据的 信息(例如,类型、数据大小、使用的压缩算法、有关缓存的提示)。与客户端请求的 HTTP 标头块类似,这些 HTTP 标头形成一个以空行结束的块。
- 最后一个块是数据块,它包含可选数据。
示例响应
成功的网页响应
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 55743
Connection: keep-alive
Cache-Control: s-maxage=300, public, max-age=0
Content-Language: en-US
Date: Thu, 06 Dec 2018 17:37:18 GMT
ETag: "2e77ad1dc6ab0b53a2996dfd4653c1c3"
Server: meinheld/0.6.1
Strict-Transport-Security: max-age=63072000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Vary: Accept-Encoding,Cookie
Age: 7
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A simple webpage</title>
</head>
<body>
<h1>Simple HTML webpage</h1>
<p>Hello, world!</p>
</body>
</html>
通知请求的资源已永久移动
HTTP/1.1 301 Moved Permanently
Server: Apache/2.4.37 (Red Hat)
Content-Type: text/html; charset=utf-8
Date: Thu, 06 Dec 2018 17:33:08 GMT
Location: https://mdn.org.cn/ (this is the new link to the resource; it is expected that the user-agent will fetch it)
Keep-Alive: timeout=15, max=98
Accept-Ranges: bytes
Via: Moz-Cache-zlb05
Connection: Keep-Alive
Content-Length: 325 (the content contains a default page to display if the user-agent is not able to follow the link)
<!DOCTYPE html>… (contains a site-customized page helping the user to find the missing resource)
通知请求的资源不存在
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=utf-8
Content-Length: 38217
Connection: keep-alive
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Content-Language: en-US
Date: Thu, 06 Dec 2018 17:35:13 GMT
Expires: Thu, 06 Dec 2018 17:35:13 GMT
Server: meinheld/0.6.1
Strict-Transport-Security: max-age=63072000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Vary: Accept-Encoding,Cookie
X-Cache: Error from cloudfront
<!DOCTYPE html>… (contains a site-customized page helping the user to find the missing resource)
响应状态码
HTTP 响应状态码 指示特定的 HTTP 请求是否已成功完成。响应被分为五类:信息响应、成功响应、重定向、客户端错误和服务器错误。