http的请求和相应报文详细介绍

607 阅读9分钟

公众号:小博的前端笔记

HTTP 报文是客户端(如浏览器)和服务器之间交换数据的核心载体,遵循特定的格式规范。它们分为两类:HTTP 请求报文(客户端发送给服务器)和 HTTP 响应报文(服务器返回给客户端)。

一、HTTP 请求报文 (Request Message)

客户端向服务器请求资源时发送的报文。

结构

<方法> <请求URL> <HTTP版本>      // 请求行 (Request Line)
<头部字段名1>: <值1>              // 请求头部 (Request Headers)
<头部字段名2>: <值2>
...
<头部字段名N>: <值N>
                                 // 空行 (CRLF - Carriage Return Line Feed)
<请求体>                          // 请求体 (Request Body - 可选)
  1. 请求行 (Request Line):

    • 方法 (Method): 定义要对资源执行的操作。常见方法:

      • GET: 请求指定资源。不应产生副作用(安全、幂等)。通常无请求体。
      • POST: 向指定资源提交数据进行处理(如提交表单、上传文件)。可能产生副作用(非幂等)。通常有请求体。
      • PUT: 替换指定资源的所有当前表示。可能产生副作用(幂等)。通常有请求体。
      • DELETE: 删除指定资源。可能产生副作用(幂等)。通常无请求体。
      • HEAD: 与 GET 相同,但服务器只返回头部,不返回响应体。用于检查资源是否存在或获取元数据(安全、幂等)。
      • PATCH: 对资源进行部分修改(非幂等)。通常有请求体。
      • OPTIONS: 请求服务器告知支持的通信选项(方法等)(安全、幂等)。
      • CONNECT, TRACE: 较少使用,主要用于代理和诊断。
    • 请求URL (Request URL): 要请求的资源的路径(有时是完整URL,有时是相对路径,取决于上下文)。例如 /index.htmlhttps://www.example.com/api/data

    • HTTP 版本 (HTTP Version): 客户端使用的 HTTP 协议版本,如 HTTP/1.1HTTP/2。影响协议行为和头部字段的语义。

  2. 请求头部 (Request Headers):

    • 由一行或多行键值对 (<字段名>: <值>) 组成,提供关于请求的附加信息。

    • 非常重要,用于控制请求行为、传递客户端信息、协商内容等。

    • 常见请求头:

      • Host: (HTTP/1.1 必需) 请求的目标主机名和端口号(如 www.example.com:8080)。虚拟主机依赖此字段。
      • User-Agent: 客户端软件标识(浏览器类型、版本、操作系统等)。
      • Accept: 客户端能够处理的媒体类型(MIME类型)及优先级(如 text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8)。
      • Accept-Language: 客户端偏好的自然语言(如 en-US, en;q=0.9, zh-CN;q=0.8)。
      • Accept-Encoding: 客户端支持的内容编码(压缩算法)(如 gzip, deflate, br)。
      • Connection: 控制本次连接是否保持打开(如 keep-alive, close)。
      • Cookie: 将之前服务器通过 Set-Cookie 设置的 Cookie 发送回服务器(如 sessionId=abc123; theme=dark)。
      • Content-Type: (当有请求体时重要) 指定请求体的媒体类型(MIME类型)(如 application/json, application/x-www-form-urlencoded, multipart/form-data)。
      • Content-Length: (当有请求体时重要) 请求体的字节长度(十进制数字)。
      • Authorization: 包含用于访问受保护资源的凭据(如 Basic YWxhZGRpbjpvcGVuc2VzYW1l, Bearer eyJhbGciOi...)。
      • Referer: 当前请求来源页面的 URL(可能被隐私设置屏蔽)。
      • Cache-Control: 指定请求/响应链中的缓存机制(如 no-cache, max-age=3600)。
  3. 空行 (Empty Line):

    • 一个只包含回车换行符 (CRLF, \r\n) 的行。
    • 至关重要! 它标志着请求头部的结束。如果请求有体,则空行之后就是请求体。
  4. 请求体 (Request Body - 可选):

    • 包含发送给服务器的数据(例如表单提交的内容、上传的文件内容、JSON/XML API 数据)。
    • 只有当方法需要时(如 POST, PUT, PATCH)才会存在。
    • 其格式和内容由 Content-Type 头部指定(如 application/json 表示 JSON 数据,multipart/form-data 表示包含文件上传的表单数据)。
    • 长度由 Content-LengthTransfer-Encoding(如分块传输 chunked)头部指示。

示例 (GET 请求)

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

示例 (POST 请求 - 提交 JSON)

POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 56
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
​
{"name": "John Doe", "email": "john.doe@example.com"}

二、HTTP 响应报文 (Response Message)

服务器处理完客户端请求后返回的报文。

结构

<HTTP版本> <状态码> <状态短语>   // 状态行 (Status Line)
<头部字段名1>: <值1>             // 响应头部 (Response Headers)
<头部字段名2>: <值2>
...
<头部字段名N>: <值N>
                                // 空行 (CRLF)
<响应体>                         // 响应体 (Response Body - 可选)
  1. 状态行 (Status Line):

    • HTTP 版本 (HTTP Version): 服务器使用的 HTTP 协议版本(如 HTTP/1.1)。

    • 状态码 (Status Code): 三位数字代码,表示请求处理的结果。

      • 1xx (信息性): 请求已接收,继续处理(如 100 Continue)。
      • 2xx (成功): 请求已成功被服务器接收、理解并接受(如 200 OK - 请求成功;201 Created - 资源已创建;204 No Content - 成功但无返回内容)。
      • 3xx (重定向): 需要客户端采取进一步的操作以完成请求(如 301 Moved Permanently - 永久重定向;302 Found / 307 Temporary Redirect - 临时重定向;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 - 服务器暂时过载或维护;504 Gateway Timeout - 网关/代理等待上游服务器响应超时)。
    • 状态短语 (Reason Phrase): 对状态码的简短文字描述(如 OK, Not Found)。主要是为了人类可读性,程序逻辑应依赖状态码。

  2. 响应头部 (Response Headers):

    • 由一行或多行键值对 (<字段名>: <值>) 组成,提供关于响应的附加信息。

    • 用于控制缓存、描述响应体、设置 Cookie、提供服务器信息等。

    • 常见响应头:

      • Server: 服务器软件名称和版本(如 Apache/2.4.41 (Ubuntu))。
      • Date: 响应生成的日期和时间(GMT)。
      • Content-Type: (当有响应体时必需) 指定响应体的媒体类型(MIME类型)(如 text/html; charset=UTF-8, application/json, image/png)。
      • Content-Length: (当有响应体时重要) 响应体的字节长度(十进制数字)。对于动态内容或分块传输时可能省略。
      • Content-Encoding: 应用于响应体的编码(压缩算法)(如 gzip)。客户端需解压。
      • Cache-Control: 指定响应的缓存策略(如 public, max-age=3600, no-store, must-revalidate)。
      • Set-Cookie: 服务器设置 Cookie 到客户端(如 sessionId=abc123; Expires=Wed, 30 Jun 2025 12:00:00 GMT; Path=/; Secure; HttpOnly)。一个响应可包含多个 Set-Cookie 头。
      • Location: (重定向时必需) 用于 3xx 响应,指示重定向的目标 URL。
      • WWW-Authenticate: (401 响应时必需) 指定访问请求资源所需的认证方案(如 Basic realm="Restricted Area")。
      • Transfer-Encoding: 指定传输响应体所使用的编码(如 chunked 用于分块传输编码)。
      • Access-Control-Allow-Origin: (CORS) 指定哪些源可以访问该资源(如 *, https://trusted-site.com)。
  3. 空行 (Empty Line):

    • 一个只包含回车换行符 (CRLF, \r\n) 的行。
    • 至关重要! 它标志着响应头部的结束。如果响应有体,则空行之后就是响应体。
  4. 响应体 (Response Body - 可选):

    • 包含服务器返回给客户端的实际数据(如请求的 HTML 页面、图片、JSON/XML API 数据、文件下载内容)。
    • 对于 HEAD 请求或某些状态码(如 204 No Content, 304 Not Modified)没有响应体。
    • 其格式和内容由 Content-Type 头部指定。
    • 长度由 Content-LengthTransfer-Encoding(如 chunked)头部指示。

示例 (200 OK - HTML 页面)

HTTP/1.1 200 OK
Date: Mon, 30 Jun 2025 10:00:00 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Cache-Control: max-age=3600
Connection: close
​
<!DOCTYPE html>
<html>
<head>
    <title>Example Page</title>
</head>
<body>
    <h1>Hello, World!</h1>
</body>
</html>

示例 (404 Not Found)

HTTP/1.1 404 Not Found
Date: Mon, 30 Jun 2025 10:01:00 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 123
​
<html>
<head><title>404 Not Found</title></head>
<body>
<h1>404 Not Found</h1>
<p>The requested URL /missing-page.html was not found on this server.</p>
</body>
</html>

示例 (302 Found - 重定向)

HTTP/1.1 302 Found
Date: Mon, 30 Jun 2025 10:02:00 GMT
Server: Apache/2.4.41 (Ubuntu)
Location: https://www.newexample.com/new-location
Content-Length: 0
Connection: close

示例 (Set-Cookie)

HTTP/1.1 200 OK
Date: Mon, 30 Jun 2025 10:03:00 GMT
Server: nginx
Content-Type: application/json
Content-Length: 45
Set-Cookie: sessionToken=xyz789; Path=/; HttpOnly; Secure
Set-Cookie: userPref=darkMode; Path=/settings; Expires=Wed, 30 Jun 2026 10:03:00 GMT

{"status": "success", "message": "Logged in"}

关键点总结

  1. 严格格式: 请求行/状态行、头部字段、空行、报文体的顺序和格式必须严格遵守规范。
  2. 头部核心作用: 头部字段是控制 HTTP 通信行为(认证、缓存、内容协商、连接管理、Cookie 等)的主要机制。理解常用头部至关重要。
  3. 空行分隔: 空行 (CRLF) 是头部结束、报文体开始的唯一标识符。缺少它会导致解析错误。
  4. 状态码: 状态码是程序判断请求成功与否的最直接依据。熟悉主要的状态码类别和常见具体状态码(200, 301, 302, 304, 400, 401, 403, 404, 500, 502, 503, 504)非常重要。
  5. 内容协商: Accept* 请求头和 Content-* 响应头共同作用,确保客户端和服务器就传输内容的最佳表示(语言、编码、类型)达成一致。
  6. 无状态性: HTTP 本身是无状态的,每个请求/响应对是独立的。Cookie/Set-Cookie 机制和 Session 管理是实现有状态交互(如登录)的关键补充。
  7. 工具: 使用浏览器开发者工具(Network 标签页)、命令行工具(如 curl -v)、网络抓包工具(如 Wireshark)是查看和分析实际 HTTP 请求和响应报文的最佳方式。