HTTP 基础:方法、状态码与请求语义
HTTP 的核心特点
HTTP 是应用层请求—响应协议。它本身是无状态的,但可以借助 Cookie、Token 和服务端 Session 关联多次请求。
常用方法
“安全”表示按协议语义不修改服务端状态;“幂等”表示执行一次和多次的预期效果相同,不代表每次响应完全相同。
请求结构与请求头
问题:HTTP 请求包括哪几部分?
答案:一个完整的 HTTP 请求通常包括请求行、请求头、空行和请求体四部分:
- 请求行:包括请求方法、请求目标和 HTTP 版本。请求目标通常包含路径和查询参数,例如
GET /users?page=1 HTTP/1.1。 - 请求头:描述请求的元信息,例如目标主机、内容格式、认证信息、缓存条件和客户端能力。
- 空行:请求头结束的标志。即使没有请求体,也需要通过这个边界区分请求头和后续内容。
- 请求体:可选,用于携带提交的数据,常见格式有 JSON、表单、纯文本和文件 multipart。
注意:路径和查询参数属于请求目标的一部分,不属于请求体;GET 通常不使用请求体,POST、PUT、PATCH 更常通过请求体提交数据。
问题:常见的请求头及作用是什么?
答案:常见请求头可以按用途分为以下几类:
最容易混淆的是:Accept 描述“我希望接收什么响应”,Content-Type 描述“我发送的请求体是什么格式”;Authorization 负责认证凭证,Cookie 主要用于携带浏览器会话信息。
常见请求头详解
Host
表示请求访问的域名和端口。HTTP/1.1 中通常是必需的。多个域名可以解析到同一个 IP,服务器会根据 Host 区分请求应该交给哪个站点或虚拟主机。
User-Agent
描述发起请求的客户端类型、操作系统和浏览器版本,常用于访问统计、兼容性处理和问题排查。它不是可靠的身份认证信息,因为客户端可以伪造。
Accept
表示客户端能够处理、希望服务端返回的媒体类型。服务端可以根据它进行内容协商,并通过响应头 Content-Type 告知最终返回的格式。
Accept: application/json 表示希望返回 JSON;*/* 表示可以接受任意媒体类型。
Accept-Language
表示客户端偏好的自然语言及优先级。服务端可以据此选择中文或英文内容,响应中也可能通过 Content-Language 标识实际语言。它只是偏好信息,不代表用户一定有权限访问某种语言资源。
Accept-Encoding
表示客户端支持的响应内容编码方式。服务端如果选择压缩,会通过响应头 Content-Encoding: br 或 Content-Encoding: gzip 说明压缩算法。压缩可以减少传输体积,但会增加压缩和解压 CPU 消耗。
Content-Type
描述当前请求体的媒体类型,服务端据此决定如何解析请求体。常见值包括:
application/json:JSON 数据。application/x-www-form-urlencoded:键值对表单数据。multipart/form-data; boundary=...:表单和文件上传。text/plain:纯文本。
它描述的是“我发送的数据是什么格式”,不是“我希望接收什么格式”;后者由 Accept 表示。
Content-Length
表示请求体的字节数,不是字符数。服务端可以根据它判断请求体何时结束。使用分块传输时,可能改用 Transfer-Encoding: chunked,此时请求体会分成多个数据块发送。
Authorization
携带身份认证凭证。常见形式有:
Bearer <token>:携带 Token,常用于 OAuth 2.0 和 JWT。Basic <base64>:携带用户名和密码的 Base64 编码结果。
Base64 不是加密方式,认证信息必须通过 HTTPS 传输,并且服务端仍需校验凭证有效期、权限和签名。
Cookie
携带当前域名下符合条件的 Cookie,常用于会话标识、登录状态和用户偏好。Cookie 通常由服务端通过响应头 Set-Cookie 设置,浏览器后续请求会自动携带符合 Domain、Path、Secure 和 SameSite 条件的 Cookie。
不要把大量业务数据直接放进 Cookie,因为 Cookie 会在符合条件的每次请求中发送,增加请求体积。
Referer
表示当前请求通常从哪个页面跳转或发起,用于来源分析、防盗链和部分安全校验。它可能受 Referrer-Policy 控制,也可能因为隐私策略被截断或不发送,因此不能作为唯一的安全依据。
Origin
表示请求来源的协议、域名和端口。它是 CORS 校验的重要依据,跨域请求和部分同源请求可能携带该请求头。服务端需要校验允许的 Origin,不能简单地对任意 Origin 都返回 Access-Control-Allow-Origin: *,尤其是涉及凭证时。
Cache-Control
控制请求的缓存行为:
no-cache:可以使用缓存,但使用前必须向服务端验证。no-store:不要读取或保存缓存。max-age=0:缓存立即视为过期,通常需要重新验证。only-if-cached:只使用已有缓存,不访问网络,常用于特殊缓存场景。
请求头的 Cache-Control 与响应头的 Cache-Control 作用对象不同:前者表达客户端本次请求的缓存要求,后者表达服务端返回资源的缓存策略。
If-None-Match
携带客户端缓存资源的 ETag,用于协商缓存。服务端比较当前资源的 ETag:如果没有变化,返回 304 Not Modified;如果发生变化,返回 200 和新的资源内容。
If-Modified-Since
携带客户端缓存资源的最后修改时间,用于和响应头 Last-Modified 配合进行协商缓存。资源未修改时返回 304。通常服务端优先使用 If-None-Match,只有没有可用 ETag 时才依赖该字段。
Connection
在 HTTP/1.x 中表达连接管理意图。keep-alive 表示请求完成后尽量复用 TCP 连接,close 表示响应完成后关闭连接。HTTP/2 和 HTTP/3 使用其他机制管理连接,不能简单照搬 HTTP/1.1 的逐跳请求头语义。
Range
请求资源的部分字节,常用于断点续传、视频拖动和大文件分段下载。服务端支持时返回 206 Partial Content,并通过 Content-Range 说明本次返回的范围;不支持时可能忽略 Range 并返回完整资源。
GET 与 POST 常见误区
- HTTP 规范没有用“能否有请求体”简单区分 GET 和 POST,但 GET 请求体缺乏通用语义,代理和框架支持也不一致。
- URL 长度限制主要来自浏览器、服务器和代理实现,不是 HTTP 协议统一规定。
- POST 不天然比 GET 安全;机密性依赖 HTTPS,权限依赖鉴权和服务端校验。
- GET 通常可缓存、可收藏、可重放,POST 默认缓存支持较弱。
状态码
2xx 成功
200 OK:请求成功。201 Created:资源创建成功,常配合Location。204 No Content:成功但无响应体。
3xx 重定向与缓存
301、308:永久重定向。302、303:实践中常把后续请求改为 GET。307、308:明确要求保留原方法和请求体。304 Not Modified:协商缓存命中,不携带新的资源实体。
4xx 客户端问题
400 Bad Request:请求格式或参数错误。401 Unauthorized:实际含义更接近“未认证”。403 Forbidden:身份已知但没有权限。404 Not Found:资源不存在。409 Conflict:资源状态冲突。429 Too Many Requests:请求过多。
5xx 服务端问题
500 Internal Server Error:服务内部错误。502 Bad Gateway:网关收到无效上游响应。503 Service Unavailable:临时不可用。504 Gateway Timeout:网关等待上游超时。
常用请求头与响应头
- 内容协商:
Accept、Accept-Language、Content-Type。 - 缓存:
Cache-Control、ETag、If-None-Match、Last-Modified。 - 身份与会话:
Authorization、Cookie、Set-Cookie。 - 跳转和资源:
Location、Content-Disposition。 - 跨域:
Origin、Access-Control-Allow-Origin。
Content-Type 描述当前消息体格式,Accept 描述客户端希望接收的格式。
HTTP/1.1、HTTP/2 与 HTTP/3
高频场景题
401 和 403 如何选择?
未登录、Token 无效通常返回 401;已经识别用户但权限不足返回 403。前端不应仅通过隐藏按钮实现权限控制,服务端必须再次鉴权。
POST 如何防止重复提交?
前端可以禁用按钮和请求去重,但最终保证通常依赖服务端幂等键、唯一约束或状态机。

