HTTP请求格式详解
总是吃不到羊的小灰灰
编辑于 2025年10月22日 19:34

前言

HTTP请求是浏览器或其他客户端和服务器之间通信的基础。一个HTTP请求由四个部分组成:请求行(request line)、请求头(headers)、空行(blank line)、请求体(body)。

请求格式

1. 请求行(Request Line)

请求行由方法(Method)、请求URI(Uniform Resource Identifier)、协议版本组成,这三部分通过空格分开。

● 方法(Method): 定义了对资源的操作,如GET、POST、PUT、DELETE等。

● 请求URI: 指定了请求的资源路径。

● 协议版本: 通常是HTTP/1.1或HTTP/2.0。

示例: GET /index.html HTTP/1.1

1. 方法(Method)

方法指明了客户端希望服务器对资源执行的操作。这个部分是一个动词或者一个名词,常见的HTTP方法包括:

○ GET: 请求获取指定资源。GET请求应当只用于获取数据而不会引发服务器上数据的改变。

○ POST: 用于提交数据,例如表单数据。POST请求可能会导致新的资源的创建或已有资源的修改。

○ PUT: 将请求的数据上传到指定的URI(如果指定的URI不存在,则创建它)。

○ DELETE: 请求删除指定的URI上可用的资源。

○ HEAD: 请求获取资源的元数据(metadata),类似于GET请求,但不返回消息体。

○ OPTIONS: 用于描述目标资源的通信选项。

○ PATCH: 用于对资源应用部分修改。

○ 其他方法(如TRACE和CONNECT)在Web应用中较少使用。

2. 请求URI

请求URI(Uniform Resource Identifier)指明了请求应当被应用的资源。它告诉服务器要获取或操作的具体资源。例如:

○ 绝对路径: /index.html 或 /images/logo.png

○ 带查询字符串: /search?q=http (q=http 是查询参数,告诉服务器按照 "http" 进行搜索)

在HTTP/1.1中,请求URI通常传递的是URI的路径和可选的查询字符串。但是在代理请求中,它可能是完整的URI。

3. 协议版本

协议版本标识了客户端用于构造请求的HTTP协议的版本。这个信息非常重要,因为它告知服务器客户端理解的协议细节和能力。常见的版本有:

○ HTTP/1.0: 较早的HTTP版本,简单并且不支持每个连接多个请求(非持续连接)。

○ HTTP/1.1: 当今最普遍的版本,支持持续连接、流水线化请求、更高效的缓存处理等。

○ HTTP/2: 最新的HTTP版本,支持多路复用、头部压缩、服务器推送等。

完整的请求行通常看起来像这样:

GET /index.html HTTP/1.1

这个请求行告诉服务器客户端想要通过GET方法获取根目录下的index.html文件,并且客户端会按照HTTP/1.1版本的规则进行通信。

每个部分由空白字符(通常是个空格)分隔。请求行后面紧接着是请求头部,由一个CRLF(回车加换行,\r\n)标识请求行的结束。在HTTP请求和响应中,CRLF用来作为消息中各个头部字段的分隔符。

2. 请求头(Request Headers)

HTTP请求头由一系列的键值对组成,它们为HTTP请求提供了额外的上下文和参数设置。以下是一些常见的请求头部字段,以及它们的含义和用途:

1. Host

○ 描述: 指定服务器的域名和(可选的)端口号。在HTTP/1.1中,Host是唯一一个必须存在的请求头。

○ 示例: Host: www.example.com

2. User-Agent

○ 描述: 包含了发起请求的客户端信息,比如浏览器类型、版本、操作系统等。

○ 示例: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)

3. Accept

○ 描述: 指明客户端能够接受的内容类型,也就是服务器可以返回的媒体资源类型。

○ 示例: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

4. Accept-Language

○ 描述: 告诉服务器客户端优先选择的语言,通常用于国际化内容。

○ 示例: Accept-Language: en-US,en;q=0.5

5. Accept-Encoding

○ 描述: 告诉服务器客户端支持的内容编码方式,比如gzip或defla te压缩。

○ 示例: Accept-Encoding: gzip, deflate, br

6. Connection

○ 描述: 控制当前事务完成后,客户端和服务器之间连接的处理方式,例如keep-alive或close。

○ 示例: Connection: keep-alive

7. Cache-Control

○ 描述: 指示请求和响应遵循的缓存机制。

○ 示例: Cache-Control: no-cache

8. Cookie

○ 描述: 包含从服务器接收的所有cookies,服务器可以用它来恢复客户端的会话状态。

○ 示例: Cookie: sessionToken=abc123; userId=789

9. Content-Length

○ 描述: 在POST或PUT请求中,指示请求体的大小(以字节计)。

○ 示例: Content-Length: 348

10. Content-Type

○ 描述: 当发送POST或PUT请求时,这个请求头必须被使用来指示提交数据的MIME类型。

○ 示例: Content-Type: application/json

11. Authorization

○ 描述: 包含了证明客户端有权查看某资源的证书。它通常涉及一个承载令牌,如JWT或OAuth令牌。

○ 示例: Authorization: Bearer YOUR_TOKEN_HERE

12. Referer

○ 描述: 指示发起请求的前一个页面的URI,可以用来跟踪从何处链接到当前请求的资源。

○ 示例: Referer: http://www.example.com/index.html

示例:

Host: example.com

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Cookie: userID=12345; sessionToken=abcdef

这些请求头部字段是用于客户端和服务器之间交换附加信息,优化请求处理和响应内容。并不是所有的头部字段都会在每个请求中出现,它们依据请求的类型和客户端的需求而变化。

在真实的HTTP通信中,还会有很多其他的请求头部字段,这些字段可以定义非标准的、实验性的或针对某个应用的特定行为。开发者有时也会自定义HTTP头部来传输特定的信息。

3. 空行(Blank Line)

头部和主体之间的空行是请求的一个重要部分,即使请求没有主体,这个空行也必须存在。它告诉服务器头部结束、接下来是请求体。

4. 请求体(Request Body)

请求体(Request Body)是HTTP请求消息的可选部分,仅在请求方法支持且需要发送数据时使用。例如,当你提交表单数据时使用POST方法,或使用PUT方法上传内容,对于GET和HEAD请求来说,通常没有请求体。请求体中包含的实际数据类型和格式取决于请求头中的 Content-Type 字段。以下是一些常见的请求体类型及其使用场景:

1. application/x-www-form-urlencoded

○ 描述: 这是最常见的请求体类型,通常用于HTML表单提交。

○ 格式: 键值对以 & 符号分隔,且键和值都为URL编码。例如,key1=value1&key2=value2。

2. multipart/form-data

○ 描述: 用于文件上传和发送表单数据时,当表单中有 字段时常用这种类型。

○ 格式: 请求体被分割成多个部分,每部分包含一个不同的表单域数据,部分之间由分隔符(boundary)隔开。

3. application/json

○ 描述: 用于发送JSON编码的数据。现代Web APIs和RESTful服务通常用这种格式。

○ 格式: JSON字符串,如 { "key1": "value1", "key2": "value2" }。

4. text/plain

○ 描述: 纯文本数据,不含任何数据类型或结构描述符。

○ 格式: 简单的文本字符串,没有特定的结构。

5. application/xml 或 text/xml

○ 描述: XML数据格式,某些服务或API可能需要使用XML格式进行数据交换。

○ 格式: 符合XML规范的字符串,例如 value1value2。

6. application/octet-stream

○ 描述: 用于传输二进制数据或文件内容,指示请求体中的数据是原始的字节。

○ 格式: 数据被当作一系列字节处理。

请求体示例:

application/x-www-form-urlencoded:

username=user1&password=pass123&email=user1%40example.com

multipart/form-data:

--boundary12345

Content-Disposition: form-data; name="file"; filename="example.txt"

Content-Type: text/plain

... file contents here ...

--boundary12345--

application/json:

{

"username": "user1",

"password": "pass123",

"email": "user1@example.com"

}

text/plain:

This is plain text.

请求体被视为消息的负载,并且根据用途可能含有不同的媒体类型、字符集编码以及内容编码(如gzip)。需要注意的是,并非所有HTTP方法都含有请求体(例如,GET和HEAD请求通常没有请求体),并且即使方法支持包含请求体,也不代表每次请求都必须包含请求体内容;这取决于具体的使用场景和需求。

示例解析

让我们来分析一个常见的HTTP POST请求,该请求通常用于用户登录功能。在这个例子中,客户端(比如Web浏览器)向服务器发送一个包含用户名和密码的请求以请求登录。

下面是请求的完整样例:

POST /login HTTP/1.1

Host: www.example.com

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate, br

Content-Type: application/json

Content-Length: 55

Connection: keep-alive

Cookie: sessionId=abc123

Upgrade-Insecure-Requests: 1

{

"username": "myUser",

"password": "myPassword123"

}

现在来逐行分析这个请求:

1. 请求行(Request Line)

POST /login HTTP/1.1

● 使用POST方法因为客户端要提交数据。

● 请求目标/login表示要对登录资源进行操作。

● HTTP版本为1.1,告诉服务器客户端可以接收HTTP/1.1的协议标准。

2. 请求头(Headers)

Host: www.example.com

● 指明要连接的服务器主机名为www.example.com。

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0

● 提供了客户端使用的浏览器和操作系统信息,这有助于服务器进行日志记录和针对性的内容优化。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

● 告诉服务器可以返回哪种类型的数据,从text/html到任意类型(*/*)。

Accept-Language: en-US,en;q=0.5

● 尝试获取英语内容。

Accept-Encoding: gzip, deflate, br

● 浏览器支持gzip、deflate和Brotli(br)压缩。

Content-Type: application/json

● 请求体中的数据类型是JSON格式。

Content-Length: 55

● 这表明随后的请求体长55个字节。

Connection: keep-alive

● 这表明客户端想要使用持久连接,避免请求结束后立即关闭TCP连接。

Cookie: sessionId=abc123

● 发送一个名称为sessionId的Cookie给服务器。

Upgrade-Insecure-Requests: 1

● 通知服务器客户端愿意接受到升级版的TLS请求。

3. 空行(Blank Line)

● 请求头和请求体之间总是存在一个空行,这里没有显示,但它必须存在。

4. 请求体(Body)

{

"username": "myUser",

"password": "myPassword123"

}

● 发送的数据是一个JSON对象包含用户名和密码字段。基于安全性考虑,实际应用中密码应该加密处理。

在这个HTTP请求示例中,客户端的行为是请求服务器验证提供的凭据并开始一个用户会话。服务器在处理这个POST请求时会读取请求头以得知如何进一步处理请求,然后读取请求体内的数据去验证用户身份。如果身份验证成功,它通常会返回一个HTTP响应,包括状态码(如200 OK),以及一个新的会话Cookie或重定向到另一个页面的头部。

总结

HTTP请求是客户端向服务器获取数据或提交数据的方式。了解其结构和内容对于理解Web开发和网络通信至关重要。在实际应用中,根据需要,不同的请求类型、头部和主体组合使用,以实现有效和安全的数据交互。