GET 和 POST 请求的区别是什么?
GET 和 POST 是 HTTP 协议中最常用的两种请求方法。它们的主要区别可以从应用场景(语义)、数据传输方式、安全性以及技术特性等几个维度来概括。
以下是详细的对比:
1. 核心区别总结表
| 特性 | GET | POST |
|---|---|---|
| 主要作用 | 获取数据(读) | 提交数据(写/修改) |
| 数据位置 | 放在 URL 中(Query String) | 放在 Request Body(请求体)中 |
| 数据可见性 | URL 中可见,隐私性差 | URL 中不可见,隐私性较好 |
| 数据长度 | 受浏览器/服务器对 URL 长度限制(通常 2KB~8KB) | 理论上无限制(受服务器配置限制) |
| 缓存/历史 | 能被缓存,保留在浏览器历史记录中 | 默认不缓存,不保留在历史记录中 |
| 书签 | 可以被收藏为书签 | 无法被收藏为书签 |
| 数据类型 | 仅支持 ASCII 字符 | 支持二进制(图片/文件)、文本、JSON 等 |
| 幂等性 | 幂等(多次请求结果一致) | 非幂等(多次请求可能创建多份资源) |
2. 详细深度解析
1. 语义与用途 (Semantics)
- GET (获取): 类似于“去图书馆借书”。目的是从服务器获取资源。它不应该对服务器的数据产生副作用(即不应该修改数据)。
- POST (发送): 类似于“去邮局寄信”或“提交表格”。目的是向服务器发送数据,通常用于创建新资源、更新数据或提交表单。
2. 数据传输方式 (Data Transmission)
- GET: 数据拼接在 URL 后面,用
?分割,参数用&连接。- 例子:
http://example.com/api?name=zhangsan&age=20
- 例子:
- POST: 数据放在 HTTP 包的 Body 中。URL 看起来很干净。
- 例子:
http://example.com/api(数据在内部传输)
- 例子:
3. 安全性 (Security)
- GET 不适合传输敏感数据(如密码)。因为 URL 会显示在浏览器地址栏、被保存在浏览器历史记录、代理服务器日志以及服务器访问日志中。任何人看一眼屏幕或日志就能看到密码。
- POST 相对安全,因为数据不在 URL 中。
- 注意: HTTP 协议本身是明文传输的。如果不使用 HTTPS (SSL/TLS) 加密,无论是 GET 还是 POST,数据在网络传输过程中都可以被抓包窃取。POST 并不代表绝对安全,只是隐蔽性稍好。
4. 幂等性 (Idempotency) —— 面试加分项
- GET 是幂等的: 无论你请求一次还是 N 次,资源的状态应该是一样的(就像你读一篇文章 10 次,文章内容不会变)。
- POST 是非幂等的: 如果你重复提交表单(比如刷新页面),可能会导致服务器产生重复的数据(比如下了两个订单,扣了两次款)。这也是为什么刷新 POST 请求页面时,浏览器会弹窗警告“确认重新提交表单”。
5. 底层传输 (TCP 数据包) —— 进阶知识
虽然 HTTP 规范没有规定,但在具体的浏览器和库的实现中,二者在 TCP 数据包发送上可能存在差异(这是一个常见的面试考点,但需注意并非所有环境都如此):
- GET: 浏览器通常会产生 1 个 TCP 数据包(Header 和 Data 一起发送)。
- POST: 浏览器(如 Firefox)通常会产生 2 个 TCP 数据包:
- 先发送 Header,服务器响应
100 Continue。 - 再发送 Body(数据)。
注:Chrome 浏览器通常会将 POST 合并为 1 个包发送,除非数据量很大。
- 先发送 Header,服务器响应
总结
- 如果你只是想查询信息,用 GET。
- 如果你要提交信息、上传文件、修改服务器状态,用 POST。