请求格式 (HTTP Request Format)
一个完整的 HTTP 请求报文由以下四部分组成,严格按照顺序排列:
-
请求行 (Request Line):
- 格式:
方法 请求目标 HTTP/版本
- 内容详解:
- 方法 (Method): 定义客户端希望对资源执行的操作。常见方法有:
GET
: 请求获取指定的资源。通常不应包含请求体(即使包含,服务器也可能忽略)。POST
: 向指定资源提交数据(如表单数据、文件上传、API 调用)。通常包含请求体。PUT
: 替换指定资源的全部内容。DELETE
: 请求删除指定的资源。HEAD
: 与GET
类似,但只请求响应头,不返回响应体。用于检查资源是否存在或获取元信息。PATCH
: 对资源进行部分修改。OPTIONS
: 请求服务器告知其支持的请求方法或其它选项(常用于 CORS 预检请求)。
- 请求目标 (Request Target): 通常是要访问的资源路径(如
/index
,/api/users
),有时也包含查询字符串(如/search?q=http
)。在代理请求中,它可能是完整的 URL。 - HTTP 版本 (HTTP Version): 声明客户端使用的 HTTP 协议版本(如
HTTP/1.1
,HTTP/2
)。这决定了服务器如何解析请求和构建响应。
- 方法 (Method): 定义客户端希望对资源执行的操作。常见方法有:
- 格式:
-
请求头 (Request Headers):
- 格式:
字段名: 字段值
- 作用: 提供关于请求本身或客户端的附加信息。每个头字段占一行。
- 常见请求头示例:
Host: www.example.com
(必需,尤其在 HTTP/1.1): 指定请求的目标服务器域名和端口号。虚拟主机依赖此头区分不同网站。User-Agent: Mozilla/5.0 ...
: 标识发起请求的客户端软件(浏览器、爬虫等)。Accept: text/html,application/xhtml+xml
: 告知服务器客户端能够理解和优先接收的响应内容类型 (MIME types)。Accept-Language: en-US, en;q=0.9, zh-CN;q=0.8
: 告知服务器客户端优先选择的自然语言。Accept-Encoding: gzip, deflate, br
: 告知服务器客户端支持的响应内容压缩算法。Content-Type: application/json
(POST/PUT/PATCH 等含请求体的方法必需): 声明请求体的媒体类型 (MIME type)。常见值:application/json
,application/x-www-form-urlencoded
,multipart/form-data
。Content-Length: 123
(POST/PUT/PATCH 等含请求体的方法必需): 声明请求体的大小(以字节为单位)。Authorization: Basic dXNlcjpwYXNzd29yZA==
或Bearer eyJhbGci...
: 提供用于访问受保护资源的凭证(如用户名密码、Token)。Cookie: sessionid=abc123; theme=dark
: 将之前服务器通过Set-Cookie
响应头设置的 Cookie 发送回服务器。Connection: keep-alive
或Connection: close
: 指示客户端对连接管理的偏好(持久连接或关闭)。Cache-Control: no-cache
: 指示服务器或中间缓存如何处理该请求的缓存。
- 格式:
-
空行 (Empty Line):
- 作用: 至关重要。这是一个只包含回车换行符 (
\r\n
) 的空行。它标志着请求头的结束。如果请求有正文,正文将紧随其后开始。没有这个空行,服务器无法区分头和体。
- 作用: 至关重要。这是一个只包含回车换行符 (
-
请求体 (Request Body):
- 作用: 包含客户端发送给服务器的实际数据。并非所有请求都有请求体(如 GET、HEAD、OPTIONS、DELETE 通常没有)。
- 内容: 格式由
Content-Type
头指定。常见形式:application/x-www-form-urlencoded
: 表单数据,格式如key1=value1&key2=value2
。multipart/form-data
: 包含文件上传的表单数据,有边界分隔。application/json
: JSON 格式的结构化数据(如您的 POST 示例)。application/xml
: XML 格式的数据。- 纯文本、二进制数据等。
- 大小: 由
Content-Length
或Transfer-Encoding
头(如chunked
)指定。
请求示例详解
-
GET 请求:
GET /index HTTP/1.1 // 请求行:方法=GET, 目标=/index, 版本=HTTP/1.1 Host: localhost:1234 // 请求头:目标主机是 localhost 的 1234 端口 // 空行 (这里看不见但存在) // 无请求体 (GET 通常没有)
-
POST 请求:
POST /api/users HTTP/1.1 // 请求行:方法=POST, 目标=/api/users, 版本=HTTP/1.1 Host: localhost:1234 // 请求头:目标主机 Content-Type: application/json // 请求头:请求体是 JSON 格式 Content-Length: 18 // 请求头:请求体长度是 18 字节 Cookie: session=1234567890 // 请求头:发送 Cookie (注意:规范写法是 `Cookie`,不是 `set-cookie`,`set-cookie`是响应头) // 空行 (这里看不见但存在) { "username": "admin", "password": "password" } // 请求体:JSON 数据 (长度18字节)
响应格式 (HTTP Response Format)
一个完整的 HTTP 响应报文也由四部分组成,严格按照顺序排列:
-
状态行 (Status Line):
- 格式:
HTTP/版本 状态码 状态描述
- 内容详解:
- HTTP 版本 (HTTP Version): 声明服务器使用的 HTTP 协议版本(通常与请求的版本匹配或低于请求版本)。
- 状态码 (Status Code): 三位数字,表示请求处理的结果。第一位数字定义类别:
1xx
(信息性): 请求已接收,继续处理。2xx
(成功): 请求已被成功接收、理解、接受。最常见的是200 OK
。3xx
(重定向): 需要客户端采取进一步的操作来完成请求(如301 Moved Permanently
,302 Found
,304 Not Modified
)。4xx
(客户端错误): 请求包含语法错误或无法完成(如400 Bad Request
,401 Unauthorized
,403 Forbidden
,404 Not Found
)。5xx
(服务器错误): 服务器在处理请求时发生错误(如500 Internal Server Error
,502 Bad Gateway
,503 Service Unavailable
)。
- 状态描述 (Reason Phrase): 对状态码的简短文字说明(如
OK
,Not Found
,Internal Server Error
)。这个描述对人类友好,但程序主要依赖状态码。
- 格式:
-
响应头 (Response Headers):
- 格式:
字段名: 字段值
- 作用: 提供关于响应的附加信息,如服务器信息、响应的内容、缓存指令、Cookie 设置等。每个头字段占一行。
- 常见响应头示例 (结合您的淘宝响应):
Server: Tengine
: 标识响应的服务器软件(Tengine 是淘宝基于 Nginx 开发的 Web 服务器)。Content-Type: text/html; charset=utf-8
: 必需。声明响应体的媒体类型 (MIME type) 和字符编码。Content-Length: 1024
: 声明响应体的大小(字节)。如果使用Transfer-Encoding: chunked
(如示例),则不应使用Content-Length
。Transfer-Encoding: chunked
: 表示响应体使用分块传输编码(常用于动态生成内容,长度事先未知)。Connection: close
: 指示服务器在发送完响应后关闭连接。Cache-Control: max-age=0, s-maxage=112
: 指示客户端和中间缓存如何缓存此响应(max-age
给浏览器看,s-maxage
给共享缓存看)。Set-Cookie: sessionid=abc123; Path=/; Expires=...
: 重要。服务器要求客户端设置一个或多个 Cookie。注意与请求头Cookie
区分。Location: /new-page
: 配合3xx
重定向状态码,指定客户端应重定向到的 URL。ETag: "13b41-PqysWfJOj/1AFZt4Pt6zXyNP0gU"
: 资源的特定版本标识符,用于缓存验证(配合If-None-Match
请求头)。Last-Modified: Thu, 03 Jul 2025 17:30:00 GMT
: 资源最后修改时间,用于缓存验证(配合If-Modified-Since
请求头)。Content-Encoding: gzip
: 声明响应体使用了 gzip 压缩(客户端需要解压)。Vary: Accept-Encoding
: 告诉缓存服务器,响应的内容会根据请求头Accept-Encoding
的不同而变化。Strict-Transport-Security: max-age=31536000
(HSTS): 强制客户端在未来一段时间内通过 HTTPS 访问该域名。X-XSS-Protection: 1; mode=block
: 启用并配置浏览器内置的 XSS 过滤器(历史遗留,现代浏览器主要依赖Content-Security-Policy
)。Date: Thu, 03 Jul 2025 17:34:49 GMT
: 响应报文生成的日期和时间。Via: cache35.l2et135-6[587,529,200-0,C], ...
: 显示请求经过的代理或网关服务器路径(用于诊断)。X-Cache: HIT TCP_MEM_HIT dirn:-2:-2
: (特定于 CDN/缓存服务器) 指示该响应是否从缓存中获取(HIT
),以及缓存的类型和位置。
- 格式:
-
空行 (Empty Line):
- 作用: 同样至关重要。这是一个只包含回车换行符 (
\r\n
) 的空行。它标志着响应头的结束。响应体将紧随其后开始。没有这个空行,客户端无法区分头和体。
- 作用: 同样至关重要。这是一个只包含回车换行符 (
-
响应体 (Response Body):
- 作用: 包含服务器返回给客户端的实际数据。
- 内容: 格式由
Content-Type
头指定。常见形式:text/html; charset=utf-8
: HTML 网页(如您的示例)。application/json
: JSON 数据(常见于 API 响应)。application/xml
: XML 数据。image/png
,image/jpeg
: 图片数据。text/css
,application/javascript
: CSS 或 JavaScript 文件。- 纯文本、二进制文件等。
- 大小: 由
Content-Length
头指定,或者如果使用了Transfer-Encoding: chunked
,则通过分块格式确定结束。
响应示例详解 (淘宝响应)
HTTP/1.1 200 OK // 状态行:版本=HTTP/1.1, 状态码=200, 描述=OK
Server: Tengine // 响应头:服务器是 Tengine
Content-Type: text/html; charset=utf-8 // 响应头:响应体是 UTF-8 编码的 HTML
Transfer-Encoding: chunked // 响应头:响应体使用分块编码 (长度未知)
Connection: close // 响应头:发送后关闭连接
Vary: Accept-Encoding, Accept-Encoding, ... // 响应头:内容会根据多个头字段变化
Date: Thu, 03 Jul 2025 17:34:49 GMT // 响应头:响应生成时间
x-server-id: 28c3d6b2523ca52cb704b8b5dcd... // 响应头:(淘宝自定义) 服务器标识
... (省略了大量淘宝特定的和缓存相关的头信息) ...
Content-Encoding: gzip // 响应头:响应体被 gzip 压缩
// 空行 (这里看不见但存在)
<!DOCTYPE html><html lang="zh-CN"> // 响应体开始:压缩分块编码的 HTML 内容 (浏览器会解压)
......
</html> // 响应体结束
关键要点总结:
- 严格顺序: 请求/响应行 -> 头字段 -> 空行 -> 体。顺序不能错。
- 空行关键: 空行是头和体之间的唯一分隔符,绝对不能省略。
- 头字段格式:
Name: Value
,每行一个头。 - 方法 vs 状态码: 请求行定义操作 (方法),状态行定义结果 (状态码)。
- Host 头: HTTP/1.1 的请求必须包含
Host
头。 - Content-Type & Content-Length: 对于包含体的请求和大多数响应,这两个头通常非常重要。
- Set-Cookie vs Cookie:
Set-Cookie
是响应头(服务器设置),Cookie
是请求头(客户端发送)。 - 压缩:
Content-Encoding
表示体被压缩(如 gzip),客户端需要解压。 - 分块传输:
Transfer-Encoding: chunked
用于动态内容或长度未知时,替代Content-Length
。 - 缓存控制:
Cache-Control
,ETag
,Last-Modified
,Expires
等头共同控制缓存行为。 - 自定义头: 应用程序可以定义自己的
X-
前缀(非强制)或其他名称的头字段(如淘宝示例中的众多x-*
头)。 - 调试工具: 使用浏览器开发者工具的“网络”(Network) 面板或命令行工具如
curl -v
可以方便地查看原始 HTTP 请求和响应格式。