HTTP协议
HTTP(超文本传输协议),属于应用层协议。基于TCP连接实现。但通信方向始终由客户端发起(HTTP/2之后已修改)
。
维度 | TCP/IP协议族(传输层/TCP) | HTTP协议(应用层) |
---|---|---|
通信方向 | 全双工(双向同时通信) | 单向(客户端→服务器请求,服务器响应) |
协议层次 | 传输层(负责数据传输可靠性) | 应用层(定义数据格式和业务逻辑) |
典型场景 | 基础网络通信(如文件传输、邮件) | 客户端获取服务器资源(如网页访问) |
主动通信能力 | 双方均可主动发送数据 | 仅客户端可主动发起请求 |
HTTP报文结构
分为请求报文与响应报文,但结构类似,都由报文首部,空行(标识首部结束)与报文主体。
请求报文:
/*HTPP协议的版本*/
GET / HTTP/1.1
/*客户端支持的内容类型*/
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
/*客户端支持的内容编码类型*/
Accept-Encoding: gzip, deflate, br, zstd
/*客户端支持的语言*/
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
/*缓存控制,0代表不使用缓存*/
Cache-Control: max-age=0
/*连接方式,keep-alive即持久连接*/
Connection: keep-alive
/*请求的主机名*/
Host: www.baidu.com
响应报文
/*HTTP协议版本及状态码,表明使用HTTP/1.1协议,请求成功*/
HTTP/1.1 200 OK
/*连接方式,保持TCP连接持久化,便于后续请求复用连接*/
Connection: keep-alive
/*响应内容的编码方式,使用gzip压缩*/
Content-Encoding: gzip
/*响应内容的类型及字符编码,内容为HTML,编码是UTF-8*/
Content-Type: text/html; charset=utf-8
/*服务器生成响应的时间(格林尼治标准时间)*/
Date: Sun, 27 Apr 2025 04:11:28 GMT
/*服务器软件信息,使用百度Web服务器,版本1.1*/
Server: BWS/1.1
/*设置Cookie,H_PS_PSSID用于存储用户会话标识,指定路径、过期时间和域名*/
Set-Cookie: H_PS_PSSID=61027_61673_62325_62337_62831_62863_62877_62885_62928_62969_63040_63050_63073; path=/; expires=Mon, 27-Apr-26 04:11:28 GMT; domain=.baidu.com
/*设置Cookie,BDSVRTM用于百度统计相关,指定路径*/
Set-Cookie: BDSVRTM=5; path=/
/*设置Cookie,BD_HOME标识是否为百度首页访问,指定路径*/
Set-Cookie: BD_HOME=1; path=/
/*启用严格传输安全,强制浏览器在一定时间(172800秒)内通过HTTPS连接*/
Strict-Transport-Security: max-age=172800
/*百度内部请求追踪ID,用于全链路性能监控和问题定位*/
Traceid: 1745727088348548045813596150688561061649
/*建议浏览器使用Edge或Chrome内核渲染页面,提升兼容性*/
X-Ua-Compatible: IE=Edge,chrome=1
/*启用跨站脚本攻击防护,当检测到可疑脚本时直接阻止渲染*/
X-Xss-Protection: 1;mode=block
/*响应采用分块传输,大文件分段发送以提升传输可靠性*/
Transfer-Encoding: chunked
报文主体(可选)
具体的响应内容,不一定要有值。比如204 No Content状态码的响应
<html>
<head>
<meta name="description" content="全球领先的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的中文网页数据库,可以瞬间找到相关的搜索结果。">
<title>百度一下,你就知道</title>
</head>
<body>
</body>
</html>
HTTP各版本之间的区别
HTTP/0.9
HTPP协议的第一个版本,诞生于1991年。是一种非常简单的协议,主要用于传输纯文本HTML页面。
功能很单一,只支持GET请求。属于三无产品
,无请求头,无响应头,无状态码。
HTTP/1.0
为了解决上述缺点,于1996年发布了HTTP/1.0版。
引入了POST/HEAD等方法,丰富了交互方式;
引入了请求头与响应头,实现了与正文的解耦;
引入了状态码,用于表示请求结果;
HTTP/1.0默认短连接,每一个请求都是独立的握手/挥手的过程,每个HTTP请求完成后,连接都会被关闭,效率很低。
如果你打开一个网页,该网页有10000个CSS/JS ,那么将会瞬间占满整个服务器资源。
HTTP/1.1
为了进一步优化性能和功能,随即在1997年发布了HTTP/1.1版
默认持久连接: keep-alive,允许一个TCP连接上发送多个请求和响应,减低了服务器监听TCP连接的压力,提高传输效率;
请求头压缩: 通过压缩请求头,减少请求头大小,降低传输压力。
分块传输: Transfer - Encoding: chunked 允许服务器在数据未完全生成时就开始传输,提高效率。
缓存机制: Cache - Control、ETag
虚拟主机: Host,允许服务器托管多个域名。
**Method增强:**新增PUT,DELET,OPTIONS等方法请求

google浏览器默认为一个域名建立6条连接,所有文件传输都使用这六条连接复用。
常见优化思路:
- 减少请求数量
将资源文件(css,js等)合并- 增减连接数量
将资源分散到不同域名下,以绕开浏览器对同一个域名的最大连接限制。
HTTP性能的关键在于低延迟而不是高宽带
,以上优化,治标不治本。并没有完全解决这些问题。
HTTP/2
随着互联网发展,移动互联网与高并发场景的增加。HTTP/1.1逐渐暴露了性能瓶颈,在2015年发布了HTTP/2版本。
HTTP/2抽象出了Stream的概念,实现了并发传输
,一个Stream就相当于HTTP/1.1的请求和响应
-
二进制分帧:
HTTP/1.1 以纯文本传输数据(如请求行、头部、实体),解析效率低且易出错;
HTTP/2 将所有数据(包括请求、响应、头部、实体)分割为 二进制帧(Frame),二进制格式更紧凑、解析更快,且消除了文本解析的歧义
-
多路复用:
HTTP/1.1 依赖多个 TCP 连接或长连接(Keep-Alive)处理并发请求,但存在 队头阻塞。HTTP/2 通过 单个 TCP 连接 同时发送多个请求 / 响应,每个请求 / 响应称为一个 流(Stream),以唯一 ID 区分,帧可交错传输,接收端按流重组数据
-
头部压缩:
HTTP/2 使用 HPACK 算法,通过 静态字典(预定义常用头部)和 动态字典(记录此次连接中出现的新头部)对头部进行压缩,减少传输数据量。
-
服务器推送:
服务端可以主动向客户端推送资源,提前将客户端可能需要的资源发送给客户端,减少等待时间。
比如客户端请求 index.html,服务器在响应 HTML 的同时,推送页面所需的 style.css 和 script.js,减少客户端的往返时间(RTT)。
HTTP2在应用层与传输层之间增加了二进制分帧层,将HTTP协议由文本协议转为了二进制协议。从而实现乱序请求与响应,之前的文本协议是做不到的。

HTTP/3
尽管 HTTP/2 解决了 HTTP/1.1 的一些性能问题,但它仍然依赖于 TCP 协议,而 TCP 协议存在一些固有的缺陷,如TCP队头阻塞,握手挥手成本较大等问题。为了解决这些问题,在 2022 年发布了 HTTP/3 版本。
HTTP/3 放弃了 TCP,转而基于 QUIC(Quick UDP Internet Connections),这是其与 HTTP/2 的根本区别。QUIC 是一个运行在 UDP 之上的通用传输层协议,集成了传输控制、加密和多路复用功能
-
基于 UDP 的快速连接建立:
HTTP/2摆脱不了TCP,建立握手需要2-3个RTT,而QUIC只需要一个RTT
-
无队头阻塞的多路复用:
HTTP/2虽然在应用层实现了多路复用,但受限于 TCP 单个连接,若 TCP 数据包丢失,滑动窗口无法向前移动,因此所有流都会阻塞。
QUIC则是给每个Stream都分配了一个独立的滑动窗口,这样使得同一个连接数的多个Stream之间没有依赖关系,互联独立控制滑动窗口,从而实现真正意义上的多路复用。
-
改进的拥塞控制与可靠性:
QUIC 使用 版本化的 ACK 机制,精确记录每个数据包的接收情况,避免 TCP 因序列号混乱导致的误判。支持多种算法(如 Cubic、BBR),并可动态调整,适应高丢包率网络(如移动蜂窝网络)。
-
内置加密与安全:
QUIC 继承 TLS 1.3 的加密能力,所有传输数据(包括握手过程和载荷)均经过加密,避免中间设备篡改或监听。
TLS 1.3 的简化握手流程与 QUIC 深度整合,减少加密带来的性能损耗。
为什么不升级TCP协议而是QUIC协议? Fast Open可以缩短连接建立时间,BBR算法可以避免拥塞和滑动窗口阻塞问题。这些都可以大大提高TCP协议的处理速度。
主要原因在于历史包袱,因为TCP协议的处理和
由操作系统内核来实现
的,所以海量的旧设备无法享受到新技术带来的便利。
特性 | HTTP/1.1 | HTTP/2 | HTTP/3 (QUIC) |
---|---|---|---|
发布时间 | 1997年(RFC 2616,后续修订) | 2015年(RFC 7540) | 2022年(RFC 9000,基于 QUIC) |
应用层协议 | 基于 TCP | 基于 TCP | 基于 UDP(通过 QUIC 实现可靠传输) |
传输层协议 | TCP | TCP | UDP + QUIC 协议(内置 TLS 加密) |
多路复用 | 每个请求单独建立 TCP 连接, 通过 Connection: keep-alive 复用连接, 但存在连接级队头阻塞(同一连接中请求需按顺序处理) |
二进制分帧(Binary Framing), 单个 TCP 连接中多路复用多个请求/响应, 消除连接级队头阻塞 ,但流内仍有队头阻塞 | QUIC 基于 UDP,每个流(Stream)独立传输, 流之间互不阻塞, 完全消除连接级和流级队头阻塞 |
头部压缩 | 无专用头部压缩,仅支持 gzip 等通用压缩(开销大) |
引入 HPACK 算法,对头部字段进行索引和霍夫曼编码,大幅减少头部开销 | 基于 QUIC 的头部压缩(类似 HPACK), 支持动态表管理,压缩效率与 HTTP/2 相近 |
连接建立 | TCP 三次握手(1 RTT), TLS 需额外 1-2 RTT(如 TLS 1.2) | TCP 三次握手(1 RTT), TLS 通过 ALPN 协商(1 RTT,TLS 1.3 优化后) | QUIC 握手集成 TLS 加密, 首次连接 1 RTT, 会话恢复可实现 0 RTT(安全模式下有限制) |
安全性 | 明文传输(HTTPS 需额外 TLS 层), 默认不加密 | 支持明文(http:// ),但推荐 HTTPS(https:// ) |
强制加密 (基于 TLS 1.3,QUIC 内置加密), 无明文传输模式 |
流控制 | 基于 TCP 协议的流控制(窗口机制) | 新增 HTTP 层流控制, 支持连接级和流级独立控制(窗口机制) | QUIC 层流控制(基于 UDP 的窗口机制), 更精细的流和连接级控制 |
优先级与依赖处理 | 无显式优先级,资源按请求顺序加载 | 支持请求优先级(通过流优先级标记), 允许服务器优先处理关键资源 | 继承 HTTP/2 的优先级机制, 基于 QUIC 流的优先级管理 |
队头阻塞 | 连接级和请求级均存在(同一连接中请求阻塞会影响后续请求) | 连接级消除 ,但流内请求仍可能阻塞(单个流内包丢失会阻塞该流) | 完全消除(每个流独立,流间包丢失不互相影响) |
协议升级方式 | 无内置升级机制,需手动切换(如 HTTP 到 HTTPS) | 通过 ALPN(Application-Layer Protocol Negotiation)在 TLS 握手时协商升级 | 通过 QUIC 版本协商(UDP 端口 443,兼容现有防火墙), 支持动态版本更新 |
错误恢复与重传 | 依赖 TCP 的重传机制(慢启动、拥塞控制) | 同 TCP 机制, 但 HTTP/2 帧级重传需依赖 TCP 层 | QUIC 内置多路复用和独立流控制, 单个流的包丢失仅重传该流数据, 拥塞控制更灵活(如 ECMP 多路径传输) |
服务器推送 | 不支持 | 支持(Server Push),可主动推送资源到客户端 | 理论上支持,但 QUIC 层未显式定义, 实际应用较少 |
默认端口 | 80(明文)、443(HTTPS) | 80(明文)、443(HTTPS)(与 HTTP/1.1 兼容) | 443(强制加密,复用 HTTPS 端口, 也可支持其他端口,但推荐 443) |
适用场景 | 老旧系统、低并发场景 | 高并发网站、需要减少延迟的场景(如单页应用) | 高延迟或网络不稳定环境(如移动网络、物联网), 追求极速连接和低延迟的场景 |
主要优势 | 兼容性强,实现简单 | 减少连接数、降低延迟、提升吞吐量 | 更快的连接建立、抗网络拥塞、消除队头阻塞 |
主要劣势 | 高延迟、队头阻塞严重、头部开销大 | 仍依赖 TCP,受限于 TCP 固有缺陷(如队头阻塞在流内残留) | 基于 UDP,可能受防火墙限制, 实现复杂度高 |
HTTP请求方式
方法 | 作用 | 场景 | 是否幂等 |
---|---|---|---|
GET | 请求资源,无请求体(并不强制) | 页面浏览,API数据查询 | 幂等,多次请求结果一致,不修改服务器状态 |
POST | 提交数据,有请求头 | 登录,评论等创建资源行为 | 非幂等,多次请求创建多个资源 |
PUT | 更新资源,全量更新 | 文件内容替换 | 幂等,全局替换,资源最终状态一致 |
PATCH | 更新资源,部分更新 | 更新用户名,修改密码,更新订单状态 | 非幂等,可能包含增量,比如修改次数等,多次执行结果可能不同 |
DELETE | 删除指定资源 | 删除博客,删除订单,用户注销 | 幂等,最终状态均为不存在 |
HEAD | 仅获取响应头部(不返回主体) | 检查资源是否存在及元信息 | 幂等,仅获取响应头,不修改服务器 |
OPTIONS | 查看服务器支持的HTTP方法 | 请求前的检查 | 幂等,用于查询服务器支持的请求方法和跨域配置,不修改服务器 |
CONNECT | 建立一个到目标资源的隧道 | 用于在客户端和服务器之间进行加密的隧道传输,.通常用于 SSL/TLS 代理 | 未定义,仅用于建立隧道,理论上是幂等 |
TRANCE | 显示服务器收到的请求 | 主要用于测试与调试,大多数服务器都会禁用TRANCE | 幂等,仅回显,不修改服务器 |
HTTP响应码
基于 **RFC 7231/7232/7233 等规范
类别 | 含义 | 首位数字 | 典型场景 |
---|---|---|---|
信息性 | 请求已接收,继续处理 | 1xx | 101 Switching Protocols (协议升级) |
成功 | 请求已成功处理 | 2xx | 200 OK 、201 Created |
重定向 | 需要进一步操作以完成请求 | 3xx | 301 Moved Permanently 、302 Found |
客户端错误 | 请求存在语法错误或无法处理 | 4xx | 404 Not Found 、403 Forbidden |
服务器错误 | 服务器处理请求时发生错误 | 5xx | 500 Internal Server Error |
1xx 信息性状态码(Informational)
状态码 | 名称 | 说明 |
---|---|---|
100 | Continue | 客户端请求的前半部分已接收,可继续发送剩余部分(如分块上传)。 |
101 | Switching Protocols | 服务器同意切换协议(如从 HTTP 切换到 WebSocket,通过 Upgrade 头)。 |
103 | Early Hints | (HTTP/2+)服务器提前返回提示信息(如资源预加载),用于优化性能。 |
2xx 成功状态码(Successful)
状态码 | 名称 | 说明 |
---|---|---|
200 | OK | 请求成功,返回请求的数据(最常用)。 |
201 | Created | 请求成功并创建新资源(如通过 POST 创建用户,返回资源 URI)。 |
204 | No Content | 请求成功但无返回内容(常用于删除操作或无需响应体的场景,如 DELETE )。 |
206 | Partial Content | 客户端请求部分内容(如 Range 头分块下载),返回指定范围的数据。 |
202 | Accepted | 请求已接收但尚未处理(用于异步处理场景,如后台任务提交)。 |
3xx 重定向状态码(Redirection)
状态码 | 名称 | 说明 |
---|---|---|
301 | Moved Permanently | 资源永久转移,后续请求应使用新 URI(浏览器会缓存新地址)。 |
302 | Found | 资源临时转移,客户端应使用原 URI 重新请求(HTTP/1.1 规范已更名为 302 Found ,原 302 Moved Temporarily 弃用)。 |
303 | See Other | 请求的响应需通过 GET 方法访问另一个 URI(常用于表单提交后跳转)。 |
304 | Not Modified | 资源未修改,可使用缓存内容(需配合 If-None-Match /If-Modified-Since 头)。 |
307 | Temporary Redirect | 临时重定向,保留原始请求方法(如 POST 重定向后仍用 POST 访问新 URI)。 |
308 | Permanent Redirect | 永久重定向,保留原始请求方法(替代旧版 301 的非标准行为)。 |
4xx 客户端错误状态码(Client Errors)
状态码 | 名称 | 说明 |
---|---|---|
400 | Bad Request | 客户端请求语法错误(如错误的 JSON 格式、无效参数)。 |
401 | Unauthorized | 请求需要身份验证(如缺少 Authorization 头,或令牌无效)。 |
403 | Forbidden | 服务器拒绝请求(即使身份验证通过,权限不足,如无访问资源的权限)。 |
404 | Not Found | 请求的资源不存在(URI 错误或资源已删除)。 |
405 | Method Not Allowed | 服务器不支持请求的方法(如对仅支持 GET 的端点使用 POST )。 |
409 | Conflict | 请求与资源当前状态冲突(如创建同名用户时的唯一约束冲突)。 |
410 | Gone | 资源已永久删除(比 404 更明确,提示用户无需再尝试)。 |
413 | Payload Too Large | 请求体过大(超过服务器限制,需配合 Content-Length 或 Transfer-Encoding 头)。 |
414 | URI Too Long | URI 过长(常见于手动构造的超长 URL)。 |
429 | Too Many Requests | 客户端请求频率过高,触发限流(需配合 Retry-After 头告知重试时间)。 |
431 | Request Header Fields Too Large | 请求头字段过长(如 Cookie 过大),服务器拒绝处理。 |
5xx 服务器错误状态码(Server Errors)
状态码 | 名称 | 说明 |
---|---|---|
500 | Internal Server Error | 服务器内部错误(通用错误码,用于未知或未处理的异常)。 |
501 | Not Implemented | 服务器不支持请求的功能(如未实现的 API 端点)。 |
502 | Bad Gateway | 代理服务器收到无效的上游响应(如上游服务器崩溃)。 |
503 | Service Unavailable | 服务器暂时不可用(如维护模式,需配合 Retry-After 头)。 |
504 | Gateway Timeout | 代理服务器等待上游服务器超时(与 502 类似,侧重超时)。 |
RESTFUL个人使用经验(未必正确)
在实践RESTFUL过程中,如果严格按照RESTFUL标准,无疑增加与前端对接的成本。
约定优于配置,因此团队内部只使用几个特定状态码,避免没有必要的沟通。
200:表示成功,响应中会返回具体信息,不再区分200,201,204
304:API缓存,响应中会返回具体信息。
400:业务异常,响应中会返回具体信息,401,403状态码由Gateway处理,微服务不再鉴权重复鉴权。
500:服务器异常
其它冷门状态码会被Gateway所处理
番外
Socket与Websocket的区别?
Socket 是网络编程的一个抽象概念,一套标准。借助Socket,开发者能够在不同主机间实现通信,屏蔽细节。它的主流实现都是基于TCP/IP协议。
WebSocket 则是建立在HTTP协议之上,由 HTML5 提出,目的是为了解决HTTP协议只能单向通信
的问题,属于应用层协议。
GET请求长度限制?
GET请求有最大长度限制,这是一个流传很久的都市谣言
。
事实上,W3C组织从来没有对GET长度做出要求
,真正限制GET长度的是浏览器(IE,Chrome,FireFox)与服务器(Nginx,Tomcat,Kestrel)。
目前使用最广泛的HTTP协议?
https://w3techs.com/technologies/history_overview/site_element/all
截至 2025 年,全球前 1000 大网站中约 30% 已部署 HTTP/3,主要集中在大型 CDN 和对性能敏感的应用(如 Google、Netflix),但仍低于 HTTP/2 的普及率(约 80%)