GET 与 POST 的区别
从语义、缓存、数据长度、安全性对比 GET 和 POST 请求
问题
GET 与 POST 有什么区别?从语义、缓存、数据长度、安全性等方面说明。
解答
语义区别
- GET:获取资源,是幂等的(多次请求结果相同)
- POST:提交数据,可能产生副作用(如创建资源)
// GET - 获取用户列表
fetch('/api/users?page=1&limit=10')
// POST - 创建新用户
fetch('/api/users', {
method: 'POST',
body: JSON.stringify({ name: 'John' })
})
缓存
- GET:可被浏览器缓存,可被 CDN 缓存,会保存在浏览器历史记录中
- POST:默认不缓存
// GET 请求可以通过 URL 直接访问缓存
// 浏览器会根据 Cache-Control、ETag 等头部决定是否使用缓存
// POST 请求需要手动设置才能缓存
fetch('/api/data', {
method: 'POST',
headers: {
'Cache-Control': 'max-age=3600' // 通常服务端不会这样做
}
})
数据传输
- GET:参数在 URL 中,受 URL 长度限制(浏览器通常限制 2KB-8KB)
- POST:参数在请求体中,理论上无大小限制(服务器可能有限制)
// GET - 参数拼接在 URL
fetch('/api/search?keyword=javascript&category=frontend')
// POST - 参数在 body 中,可传输大量数据
fetch('/api/upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: '大量数据...',
files: [/* 文件数据 */]
})
})
安全性
两者在传输层面安全性相同(都需要 HTTPS 加密),区别在于:
- GET:参数暴露在 URL 中,会被浏览器历史、服务器日志记录
- POST:参数在请求体中,相对不易泄露
// 不安全 - 密码暴露在 URL 中
fetch('/api/login?username=admin&password=123456')
// 相对安全 - 密码在请求体中
fetch('/api/login', {
method: 'POST',
body: JSON.stringify({
username: 'admin',
password: '123456'
})
})
对比表格
| 特性 | GET | POST |
|---|---|---|
| 语义 | 获取资源 | 提交数据 |
| 幂等性 | 幂等 | 非幂等 |
| 缓存 | 可缓存 | 默认不缓存 |
| 数据位置 | URL 参数 | 请求体 |
| 数据大小 | 受 URL 长度限制 | 理论无限制 |
| 回退/刷新 | 无害 | 数据会重新提交 |
| 书签 | 可收藏 | 不可收藏 |
关键点
- GET 用于获取数据,POST 用于提交数据,这是最本质的语义区别
- GET 请求可被缓存、收藏、保存在历史记录中,POST 不行
- GET 参数在 URL 中有长度限制,POST 在请求体中无此限制
- 两者传输安全性相同,但 GET 参数更容易被记录和泄露
- 选择依据:查询用 GET,修改用 POST,敏感数据用 POST
目录