一个典型的 HTTP 会话

在客户端-服务器协议(如 HTTP)中,会话包含三个阶段:

  1. 客户端建立 TCP 连接(如果传输层不是 TCP,则建立相应的连接)。
  2. 客户端发送请求,并等待响应。
  3. 服务器处理请求,发送回响应,提供状态码和相应数据。

从 HTTP/1.1 开始,连接在完成第三阶段后不再关闭,客户端现在可以发出进一步的请求:这意味着第二和第三阶段现在可以执行任意次。

建立连接

在客户端-服务器协议中,由客户端建立连接。在 HTTP 中打开连接意味着在底层传输层(通常是 TCP)中启动连接。

对于 TCP,计算机上 HTTP 服务器的默认端口是端口 80。也可以使用其他端口,例如 8000 或 8080。要获取的页面的 URL 包含域名和端口号,但如果端口号是 80,则可以省略。有关更多详细信息,请参阅URL 参考

注意:客户端-服务器模型不允许服务器在没有明确请求的情况下向客户端发送数据。但是,各种 Web API 实现了此用例,包括 Push APIServer-sent eventsWebSockets API

发送客户端请求

一旦建立连接,用户代理就可以发送请求(用户代理通常是 Web 浏览器,但也可以是其他任何东西,例如爬虫)。客户端请求由文本指令组成,这些指令由 CRLF(回车符,后跟换行符)分隔,分为三个块:

  1. 第一行包含请求方法及其参数

    • 文档的路径,作为不带协议或域名的绝对 URL
    • HTTP 协议版本
  2. 后续行表示 HTTP 头,向服务器提供有关适当数据类型(例如,语言、MIME 类型)的信息,或更改其行为的其他数据(例如,如果已缓存则不发送响应)。这些 HTTP 头形成一个块,以空行结束。

  3. 最后一个块是可选的数据块,其中可能包含主要由 POST 方法使用的更多数据。

请求示例

获取 developer.mozilla.org 的根页面 (https://mdn.org.cn/),并告知服务器如果可能,用户代理更喜欢法文页面

http
GET / HTTP/1.1
Host: developer.mozilla.org
Accept-Language: fr

请注意最后一行空行,它将数据块与头块分隔开。由于 HTTP 头中没有提供 Content-Length,因此此数据块为空,标记了头的结束,允许服务器在收到此空行时立即处理请求。

例如,发送表单结果

http
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

请求方法

HTTP 定义了一组请求方法,指示要对资源执行的所需操作。虽然它们也可以是名词,但这些请求方法有时被称为 HTTP 动词。最常见的请求是 GETPOST

  • GET 方法请求指定资源的数据表示。使用 GET 的请求只应检索数据。
  • POST 方法将数据发送到服务器,以便它可以更改其状态。这是HTML 表单常用的方法。

服务器响应结构

连接代理发送请求后,Web 服务器会处理它,并最终返回响应。与客户端请求类似,服务器响应由文本指令组成,由 CRLF 分隔,但分为三个块:

  1. 第一行,即状态行,包含所用 HTTP 版本的确认,后跟响应状态码(及其易于理解的简短含义)。
  2. 后续行表示特定的 HTTP 头,向客户端提供有关发送数据的信息(例如,类型、数据大小、使用的压缩算法、缓存提示)。与客户端请求的 HTTP 头块类似,这些 HTTP 头形成一个以空行结束的块。
  3. 最后一个块是数据块,其中包含可选数据。

响应示例

成功的网页响应

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 basic webpage</title>
</head>
<body>
  <h1>Basic HTML webpage</h1>
  <p>Hello, world!</p>
</body>
</html>

通知请求的资源已永久移动

http
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
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 请求是否已成功完成。响应分为五类:信息响应、成功响应、重定向、客户端错误和服务器错误。

  • 200: OK。请求已成功。
  • 301: Moved Permanently。此响应代码表示请求资源的 URI 已更改。
  • 404: Not Found。服务器找不到请求的资源。

另见