post和get请求的区别
打开浏览器开发者工具,请求切到 Network 面板,请求刷新一个网页,请求你会看到一堆请求密密麻麻排列着。请求点开任意一条,请求Method 那一栏写着 GET 或 POST。请求大多数人扫一眼就过了,请求但这两个东西的请求差别,比很多人想象中要大。请求
最直观的请求区别藏在 URL 里。GET 请求把所有参数直接拼在地址后面,请求用问号开头,请求键值对之间用 & 连接。请求你在搜索引擎里敲完关键词按下回车,请求地址栏瞬间变成一长串带 ?请求q= 的 URL,这就是 GET。POST 不一样,参数塞在请求体(request body)里,地址栏干干净净,看不到你提交了什么。
这个差异带来的第一个后果是安全性。GET 的参数暴露在 URL 中,浏览器历史记录、服务器访问日志、代理服务器缓存,到处都会留下痕迹。用 GET 传密码?等于把密码写在明信片上寄出去。POST 的参数在请求体里,虽然也不是加密的(HTTP 明文传输下都能被抓包),但至少不会大剌剌地出现在日志和地址栏里。所以登录表单、支付信息,清一色用 POST。
第二个后果跟数据长度有关。不同浏览器和服务器对 URL 长度的限制不一样,IE 曾经卡在 2083 个字符,Chrome 宽松得多,但总归有个上限。POST 理论上没有长度限制,取决于服务器配置。要上传一张图片或者一段 JSON,GET 根本扛不住。
但 GET 有个 POST 比不了的优势:幂等性。这个词听起来学术,说白了就是同一个请求发一次和发一百次,结果一样。GET /articles/123 不管你请求多少遍,返回的都是那篇文章,不会因为多请求几次就多出一篇。POST 则不然,每发一次就可能创建一条新记录。你在电商网站点两次“提交订单”,很可能生成两笔订单——这就是 POST 不幂等带来的现实问题。
幂等性还决定了另一个行为差异:浏览器可以放心缓存 GET 请求的结果,后退、刷新都很自然。POST 不行,你刷新一个 POST 提交后的页面,浏览器会弹窗问“是否重新提交表单”,因为它不确定重复提交会不会造成副作用。
还有一层容易被忽略的差别在语义层面。HTTP 规范里,GET 的语义是“获取资源”,POST 是“处理数据”。RESTful API 设计严格遵循这个约定:查用 GET,增用 POST,改用 PUT/PATCH,删用 DELETE。但现实中有不少开发者图省事,查询也用 POST,理由是“参数太长”或者“不想暴露查询条件”。这不算错,但破坏了 HTTP 的语义约定,缓存、书签、分享链接这些能力都会打折扣。
我见过一个典型的翻车案例:某后台系统用 GET 做删除操作,链接形如 /delete?id=5。结果有个同事把这条 URL 粘贴到聊天群里,有人手贱点了一下,数据就没了。GET 应该是安全的(safe),所谓安全是指不改变服务器状态。删除用 GET,等于把一把上了膛的枪放在桌上。
回到实际开发。选 GET 还是 POST,判断标准其实就几条:这个操作要不要改数据?要改,用 POST。参数会不会太长?会,用 POST。需不需要被缓存或收藏?需要,用 GET。参数里有没有敏感信息?有,用 POST 加 HTTPS。剩下的场景,GET 通常更合适。
说到底,GET 和 POST 都是 HTTP 协议里的方法,它们在底层传输上用的是同一个 TCP 连接,差别不在“管道”本身,而在使用约定和浏览器/服务器对这些约定的处理方式。理解这一点,比背面试题有用得多。
(责任编辑:休闲)
