Get请求和Post请求区别
说明:以下内容如有侵权,请联系删除
🌐 GET 与 POST 的区别与本质分析
本文从 HTTP 协议、浏览器实现、TCP 传输层 等多个角度,对 GET 与 POST 请求的区别进行系统说明。
🧩 一、从 HTTP 协议角度来看
对比项 | GET | POST |
---|---|---|
参数传递 | 通过 URL 传递(放在请求行中) | 通过请求体(Request Body)传递 |
安全性 | 参数直接暴露在 URL 中,容易被缓存、记录或篡改,不适合传输敏感信息 | 参数在请求体中,避免暴露在 URL,但若非 HTTPS,仍为明文传输 |
编码方式 | 仅支持 URL 编码(application/x-www-form-urlencoded ) | 支持多种编码方式(如 application/x-www-form-urlencoded 、multipart/form-data 、application/json ) |
缓存特性 | 浏览器和中间代理可缓存(符合幂等性) | 默认不缓存(除非显式声明 Cache-Control 或 ETag) |
速度差异 | 理论上略快(因可缓存、无请求体),但在现代网络中差异可忽略 | 含请求体,整体性能差异极小 |
数据包行为 | 一般一次性发送(Header + URL 参数) | 可能分两步发送(Header → Body),底层 TCP 可拆分为多个数据包,但这并非协议规定 |
⚠️ 注意:
“GET 只产生一个包、POST 产生两个包” 是一种常见误解。
实际上 HTTP 并没有规定“GET 一个包、POST 两个包”;是否分成两个 TCP 包取决于:
(1)是否启用了 Expect: 100-continue;
(2)请求体大小;
(3)TCP 的 MTU、Nagle 算法、操作系统发送缓冲区策略。
“POST 请求可能会分两步发送(先头后体),因此在底层可能会形成多个 TCP 包,但这并非协议要求。
🧭 二、从浏览器角度来看
特性 | GET | POST |
---|---|---|
URL 长度限制 | 有限制(浏览器与服务器各自约束,常见为 2KB~8KB) | 理论无限制(受内存与服务器配置约束) |
请求流程 | 浏览器直接发送 Header + URL,一次请求完成 | 某些浏览器或框架会: ① 先发送 Header(含 Expect: 100-continue )② 等服务器响应 100 Continue 后再发 Body |
可见性 | URL 参数可见 | 请求体内容不可直接见(但仍可通过抓包工具查看) |
幂等性 | 幂等(多次执行结果相同) | 非幂等(可能多次修改服务器状态) |
🔍 三、本质区别
从 协议层面 而言,GET 与 POST 并无底层区别——二者都是基于 TCP 的 HTTP 请求,差异主要体现在:
- 语义层面:GET 表示“获取资源”,POST 表示“提交或创建资源”;
- 实现层面:浏览器、服务器、缓存代理等对二者的行为处理方式不同;
- 习惯层面:GET 常用于查询,POST 常用于表单提交或上传。
✅ 换句话说:GET 与 POST 的差别在“约定与语义”,而非“协议与机制”。
💬 四、GET 请求是否可以有请求体(Request Body)
问题 | 说明 |
---|---|
GET 能否携带请求体? | ✅ 可以。从 HTTP/1.1 规范(RFC 7231 §4.3.1)来看,GET 允许带请求体。 |
服务器是否处理? | ❌ 大多数服务器与框架(如 Tomcat、Flask、Express)会忽略 GET 的请求体。 |
浏览器能否发送? | 🚫 常见浏览器不会发送带请求体的 GET(除非修改内核或使用自定义 HTTP 客户端)。 |
可行场景 | 可用 curl 、Postman 或自定义 Socket 手动构造有请求体的 GET 请求,用于实验或特定 API。 |
🧱 五、补充说明
🧩 1. 特殊字符问题
GET 请求的参数放在 URL 中,如果包含特殊字符(如 {}
, []
, #
, ?
, &
, =
等),
必须进行 URL 编码,否则可能导致请求失败或被服务器拒绝。
因此:
- 传输 JSON、XML、二进制数据时更适合使用 POST;
- POST 请求体中字符无需再进行 URL 编码,除非 Content-Type 要求。
🧩 2. 安全性补充
- 无论 GET 还是 POST,只要使用 HTTP 明文传输,数据都能被中间人截获;
- 要确保安全,必须使用 HTTPS(HTTP over TLS);
- GET 请求的敏感参数会被:
- 浏览器历史记录保存;
- 服务器日志记录;
- 代理或 CDN 缓存;
- 甚至暴露在 Referer 头中。
因此,不要在 GET 参数中传递密码、令牌等敏感信息。
🧠 六、核心总结
对比点 | GET | POST |
---|---|---|
参数位置 | URL(Query String) | 请求体(Body) |
安全性 | 暴露参数,不适合敏感信息 | 相对安全(但非加密) |
缓存 | 默认可缓存 | 默认不可缓存 |
幂等性 | 是 | 否 |
URL 长度 | 有限制 | 无明显限制 |
编码方式 | URL 编码 | 多种 Content-Type |
是否有请求体 | 理论上可有(通常被忽略) | 必然有 |
是否分包 | 取决于 TCP 行为(非协议规定) | 同上 |
常见用途 | 获取资源、查询 | 提交表单、上传、修改数据 |
📘 七、一句话总结
从 HTTP 的角度看,GET 与 POST 的区别在语义与惯例;
从浏览器的角度看,区别在实现与约束;
从安全的角度看,区别在是否使用 HTTPS。
作者总结:
GET 用于“取”,POST 用于“存”;
GET 是“幂等的”,POST 是“有副作用的”;
GET 的“方便”是缓存和可见,POST 的“优势”是灵活与安全。