HTTP 核心概念:特点、状态码、方法与无状态
一、先说结论
如果把 HTTP 最核心的内容压缩成几句话,可以这么记:
- HTTP 是应用层协议
- HTTP 采用请求-响应模型
- HTTP 本身是无状态的
- HTTP/1.1 和 HTTP/2 通常跑在 TCP 上,HTTP/3 跑在 QUIC/UDP 上
- GET 更偏获取资源,POST 更偏提交数据
- 真正的登录状态通常要靠 Cookie、Session、Token 等机制补充
很多面试题比如:
- HTTP 是什么?
- HTTP 有哪些特点?
- 常见状态码有哪些?
- GET 和 POST 的区别是什么?
- HTTP 为什么说是无状态协议?
- Cookie、Session、Token 分别是什么?
本质上都可以归到这篇文章里一起理解。
二、HTTP 到底是什么
HTTP,HyperText Transfer Protocol,超文本传输协议,是 Web 世界最核心的应用层协议之一。
最开始它主要用于传输网页文本,后来逐渐演化成一个通用的应用层协议,可以承载:
- HTML
- JSON
- 图片
- 视频
- 文件
- 表单数据
HTTP 关注的是:
客户端和服务端之间,应用数据应该如何组织、如何请求、如何响应。
所以 HTTP 解决的是“应用程序怎么对话”的问题,而不是“底层怎么可靠传输”的问题。
三、HTTP 的几个核心特点
1. 应用层协议
HTTP 位于应用层,它本身并不负责丢包重传、拥塞控制、流量控制这些事情。
这些能力通常由下层传输协议提供:
- HTTP/1.0、HTTP/1.1、HTTP/2:通常基于 TCP
- HTTP/3:基于 QUIC,而 QUIC 底层使用 UDP
所以常说:
- HTTP 负责表达应用语义
- TCP/QUIC 负责把这些数据可靠地送过去
2. 请求-响应模型
HTTP 的交互模式通常是:
- 客户端发请求
- 服务端回响应
例如浏览器访问网页时:
GET /index.html HTTP/1.1
Host: example.com服务端返回:
HTTP/1.1 200 OK
Content-Type: text/html
<html>...</html>因此 HTTP 更像“一问一答”的模型,而不是像 WebSocket 那样双方都可以随时主动发消息。
3. 无状态
HTTP 本身不会自动记住两次请求之间的上下文。
也就是说:
- 第一次请求是谁发的
- 这个人刚才有没有登录
- 他上一次做了什么
HTTP 协议本身都不会自动帮你保存。
所以常说:
HTTP 是无状态协议
注意,这并不代表网站不能记住用户登录状态,而是说:
记住状态这件事不是 HTTP 自己做的,而是要依赖其他机制补充。
4. 可扩展、可传多种数据
HTTP 有很多可扩展元素:
- 方法(GET、POST、PUT、DELETE)
- 状态码(200、404、500)
- 请求头 / 响应头
- 请求体 / 响应体
这使得它既能支持网页访问,也能支持 API 调用、文件传输和各种系统间通信。
四、HTTP 报文格式长什么样
1. 请求报文
HTTP 请求报文通常由四部分组成:
- 请求行
- 请求头
- 空行
- 请求体
例如:
POST /login HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 38
{"username":"alice","password":"123"}其中:
POST /login HTTP/1.1是请求行Host、Content-Type等是请求头- 空行表示头结束
- JSON 数据属于请求体
2. 响应报文
HTTP 响应报文通常由四部分组成:
- 状态行
- 响应头
- 空行
- 响应体
例如:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 19
{"code":0,"msg":"ok"}其中:
HTTP/1.1 200 OK是状态行Content-Type等是响应头- 最后的 JSON 是响应体
五、HTTP 常见状态码
状态码本质上是在告诉客户端:
这次请求处理结果怎么样。
1. 2xx:成功
200 OK
表示请求成功,服务端已经正常返回结果。
这是最常见的成功状态。
2. 3xx:重定向
301 Moved Permanently
表示资源已经永久迁移到新地址。
常见场景:
- HTTP 跳 HTTPS
- 老域名永久跳到新域名
302 Found
表示资源临时跳转到另一个地址。
更强调:
这次先去别处找,但原地址未来可能还会继续使用。
浏览器看到 301 / 302 时,通常会结合服务端返回的 Location 头自动发起下一次请求,所以表面现象都是“自动跳转”,但 301 强调永久迁移,302 强调临时跳转。
304 Not Modified
表示资源没有变化,可以继续使用本地缓存。
它通常出现在浏览器做协商缓存时。
例如浏览器带上:
If-Modified-SinceIf-None-Match
服务端检查后发现内容没变,就返回 304,而不是重新下发完整资源。
注意:
304 只会出现在协商缓存里,不会出现在强缓存直接命中的场景里。
3. 4xx:客户端问题
400 Bad Request
表示请求报文本身有问题,比如:
- 参数格式错误
- 缺少必要字段
- 请求内容不符合服务端预期
401 Unauthorized
表示当前请求没有通过身份认证。
常见场景:
- 没登录
- Token 无效
- 认证信息缺失
可以简单记成:
你还没证明你是谁。
403 Forbidden
表示服务端知道你是谁,但:
你没有权限访问这个资源。
可以简单记成:
你身份没问题,但权限不够。
404 Not Found
表示请求的资源不存在。
常见场景:
- 路径写错
- 资源被删了
- 路由没匹配上
4. 5xx:服务端问题
500 Internal Server Error
表示服务端内部处理时出错了。
它通常是一个比较通用的“服务端炸了”信号。
502 Bad Gateway
通常出现在网关、反向代理场景下,表示:
网关去请求后端服务时,后端返回了一个异常响应,或者网关拿到了无效响应。
常见于:
- Nginx 代理后端时,后端挂了
- 上游服务返回了不符合预期的响应
504 Gateway Timeout
也通常出现在网关、代理场景下,表示:
网关去请求上游服务时,等太久都没等到结果。
所以 502 和 504 的区别是:
- 502:上游回了,但回得不对
- 504:上游没及时回
503 Service Unavailable
表示服务当前暂时不可用。
它和 500 的区别在于:
- 500 更偏服务端内部处理出错
- 503 更偏服务当前接不了活,但未来可能恢复
常见场景包括:
- 服务过载
- 限流
- 熔断降级
- 维护中
六、GET 和 POST 的区别
1. 请求语义不同
GET(获取资源)
更偏向:
获取资源
例如:
- 获取用户信息
- 查询订单列表
- 获取文章详情
POST(提交数据)
提交数据,由服务端进行处理
例如:
- 登录
- 创建订单
- 提交表单
- 上传文件
2. 参数位置通常不同
GET(URL 查询参数)
参数通常放在 URL 查询串里:
/user?id=1&name=tomPOST(请求体传参)
3. 幂等性不同
GET(通常幂等)
通常认为是幂等的。
也就是说,多次请求同一个资源,不应该改变资源状态。
POST(通常非幂等)
例如创建订单接口,调一次和调两次,结果可能不一样。
4. 缓存和可分享性不同
GET 更天然适合:
- 浏览器缓存
- 书签收藏
- 链接分享
POST 通常不适合直接通过 URL 分享完整请求语义。
5. 一个面试提醒
不要简单回答“GET 在 URL,POST 在 body”就结束。
更核心的差异其实是:
- 语义
- 幂等性
- 典型使用场景
6. 什么是幂等
幂等指的是:
同一个操作执行 1 次和执行 N 次,对资源最终状态的影响是一样的。
它关注的不是“过程有没有重复执行”,而是:
最后资源状态有没有变化。
7. GET、POST、PUT、DELETE 哪些通常被认为是幂等的
通常可以这样记:
- GET:通常幂等,因为只是获取资源
- POST:通常非幂等,因为常用于创建资源或触发处理动作
- PUT:通常幂等,因为更偏把资源更新成某个确定状态
- DELETE:通常幂等,因为资源删掉后,再删一次最终状态仍然是“已删除”
一句口诀:
- GET:查,通常幂等
- POST:提,通常非幂等
- PUT:覆盖更新,通常幂等
- DELETE:删,通常幂等
七、为什么说 HTTP 是无状态协议
HTTP 的无状态指的是:
协议本身不会自动保存前后两次请求之间的上下文信息。
例如:
- 用户第一次请求
/login - 第二次请求
/profile
单从 HTTP 协议本身看,它并不知道这两个请求是不是同一个人发的。
所以如果想维持“登录状态”,就必须额外引入状态机制。
八、Cookie、Session、Token 分别是什么
这三个概念很容易混,但它们其实不是同一层东西。
1. Cookie
Cookie 是:
浏览器保存在本地的一小段数据
服务端可以通过响应头下发:
Set-Cookie: sessionId=abc123浏览器后续请求会自动带上:
Cookie: sessionId=abc123所以 Cookie 更像:
客户端的一个存储与自动携带机制
2. Session
Session 是:
服务端保存的一份会话状态
常见模式是:
- 服务端把用户登录信息存在服务端
- 给浏览器一个
sessionId - 浏览器把这个
sessionId放在 Cookie 里 - 下次请求自动带回来
- 服务端根据
sessionId找到对应 Session
所以:
- Cookie 在客户端
- Session 在服务端
3. Token
Token 是:
服务端签发给客户端的一段身份凭证
客户端后续请求时带上它,服务端校验它是否合法。
例如:
Authorization: Bearer xxxxxxToken 常见于:
- 前后端分离系统
- 微服务系统
- App / 小程序 / 多端接入
4. 三者关系怎么记
可以这样记:
- Cookie:浏览器保存和自动携带数据的方式
- Session:服务端保存登录状态的机制
- Token:客户端拿着的身份凭证字符串
5. 为什么 HTTP 无状态还能做登录
因为:
状态不是 HTTP 自己记住的,而是靠 Cookie / Session / Token 这些机制额外补上的。
6. 为什么负载均衡后会有 Session 一致性问题
如果 Session 只保存在单机内存中,那么同一个用户的请求在负载均衡后被分发到不同机器时,就可能出现“第一次登录成功,第二次又像没登录”的现象。
例如:
- 第一次请求打到 A,Session 建在 A
- 第二次请求打到 B,但 B 没这份 Session
- 浏览器虽然带着同一个
sessionId,B 仍然识别不出来
常见解决方案有三类:
- Session 粘滞:让同一个用户尽量固定访问同一台机器
- Session 同步:把 Session 从一台机器复制到其他机器
- 统一存储:把 Session 放到 Redis 等共享存储中,让所有节点读同一份数据
工程上更常见的是:
用 Redis 等共享存储解决 Session 一致性问题。
7. 为什么 Token 更适合分布式系统
Token 更适合分布式,不是因为它“更高级”,而是因为它:
不需要把登录状态强依赖在某一台机器的本地内存里。
客户端登录后拿到 Token,后续每次请求都自己带上。这样任意服务节点通常都可以独立完成校验,更适合:
- 多机部署
- 负载均衡随机分发
- 微服务调用链路透传
- 前后端分离和多端接入
当然,Token 也不是绝对无状态,像黑名单、刷新、强制下线等场景仍然可能需要服务端维护额外状态。
九、浏览器缓存和 HTTP 缓存头有哪些
浏览器缓存是一个更大的概念,指浏览器为了提速把资源保存在本地;而 HTTP 缓存是其中最常见的一种,依赖的是请求头 / 响应头。
1. 强缓存
强缓存命中时:
浏览器直接使用本地缓存,不会向服务端发送请求。
最常见的头有:
Cache-ControlExpires
其中现代更核心的是 Cache-Control。
例如:
Cache-Control: max-age=3600表示在 3600 秒内,浏览器可以直接使用本地缓存。
2. 协商缓存
协商缓存会发请求给服务端,但会带上校验信息,让服务端判断资源是否变化。
最常见的两组头是:
ETag/If-None-MatchLast-Modified/If-Modified-Since
如果资源没变,服务端返回 304 Not Modified;如果资源变了,服务端返回 200 和新的资源内容。
3. 强缓存和协商缓存怎么记
- 强缓存:本地直接用,连请求都不发
- 协商缓存:会发请求,服务端决定还能不能继续用
十、常见请求头里通常有哪些字段
这里不是让你硬背一堆字段,而是先有整体认识。
常见请求头
Host:当前访问的主机名User-Agent:客户端信息Accept:客户端能接收什么类型的数据Content-Type:请求体的数据类型Content-Length:请求体长度Authorization:认证信息Cookie:浏览器携带的 CookieConnection:例如keep-alive或close
这些请求头本质上是在补充:
这次请求的上下文信息和传输控制信息
十一、面试里怎么回答会比较顺
如果面试官让你概括 HTTP,可以这样答:
HTTP 是应用层的超文本传输协议,采用请求-响应模型,本身是无状态的。它定义了客户端和服务端之间请求报文和响应报文的格式,并通过方法、状态码、请求头、响应头等机制表达不同语义。常见状态码有 200、301、302、304、400、401、403、404、500、502、504 等;常见方法里,GET 更偏获取资源,POST 更偏提交数据。由于 HTTP 本身无状态,所以通常还需要借助 Cookie、Session、Token 等机制来维护登录状态。
十二、一句话总结
HTTP 这条主线可以压缩成一句话:
HTTP 负责定义“怎么请求和响应”,但它不负责记住你是谁,也不负责保证你和上一次还是同一个人。
