那天在公司茶水间闲聊,有人突然问一句:“为啥我们最近把所有接口都改成POST请求了啊?不是GET也能传参么?”这个问题其实挺常见的,很多新手刚接触 REST API 的时候都会有点迷惑。表面上看,GET和POST都能传数据,改成 POST 好像还麻烦了,可真要深入聊下去,背后有一堆细节。
GET 的问题其实不少
我以前写后台接口时也喜欢用GET,因为方便,URL 一拼就能调试。但很快踩坑:参数多了之后 URL 就特别长,有些浏览器或者代理服务器对 URL 长度有限制,直接给你截断。再比如登录接口,如果用GET带账号密码,那参数就会明晃晃地出现在浏览器历史、nginx 日志里,安全风险就很大。
还有缓存问题。GET请求天生可能被浏览器或者中间的 CDN 缓存掉,有时候是好事,比如拿静态资源;但如果你是下单、转账这种场景,用GET就可能出现“我点一次按钮,结果请求被缓存了,后台根本没收到”的尴尬。
为什么 POST 更稳妥
POST就不一样了,它设计出来就是为了提交数据的。请求体里可以放 JSON,大小也基本没有严格限制,更适合复杂结构的参数。而且绝大多数代理、中间件不会缓存 POST 请求,天然避免了很多幺蛾子。
再说安全性,虽然 HTTPS 已经能加密,但把敏感数据藏在 body 里,总比放在 query string 上让人肉眼可见要靠谱吧。你翻过生产环境的 nginx access.log 吗?要是上面全是GET /login?username=xxx&password=123456,那画面太美。
统一用 POST 带来的好处
有的团队就索性规定:所有接口统一 POST,开发起来不用纠结。比如请求就约定这样写:
@RestController
@RequestMapping("/api/user")
public class UserController {
@PostMapping("/login")
public ResponseEntity<String> login(@RequestBody LoginRequest request) {
if ("admin".equals(request.getUsername()) && "123456".equals(request.getPassword())) {
return ResponseEntity.ok("登录成功");
}
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("账号或密码错误");
}
}
请求的时候也很自然:
POST /api/user/login
Content-Type: application/json
{
"username": "admin",
"password": "123456"
}
这样做还有个隐形优势:网关层可以统一做参数校验、鉴权、日志采集,不用针对GET和POST写两套逻辑。
什么时候还能用 GET?
当然,也不是说 GET 就一无是处。比如查一个商品详情、获取配置信息,这种只读、不涉及敏感数据的接口,用 GET 更直观,还能被缓存利用起来。只是很多团队为了避免踩坑,干脆全改成 POST,把一致性放在第一位。
所以回到那个问题——“为啥突然要求全用 POST?”其实是出于安全、稳定和统一规范的考虑。对业务来说可能就是一个小决定,但对系统长期运维和风控来说,省下的麻烦可多了。
你们项目里现在是 GET、POST 混着用,还是已经一刀切 POST 了?