探究 GET 和 POST 的区别是什么?
探究 GET 和 POST 的区别是什么?
因为面试时候提问到,对于我这个新人来说get的作用就是从服务器拿数据,从地址栏传值,而post就是增删改代表向服务器提交数据,在body里传递数据。所以为了再详细了解其中的区别而写这篇随笔。建议直接拉到底部看那两篇参考,很细。
一、w3school 给的比较
GET | POST | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 |
历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 | 无限制。 |
对数据类型的限制 | 只允许 ASCII 字符。 | 没有限制。也允许二进制数据。 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET ! | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
可见性 | 数据在 URL 中对所有人都是可见的。 | 数据不会显示在 URL 中。 |
二、GET POST 传值
GET和POST本质上没有区别
通常来说 GET 发送数据是放在 URL 中,POST 是放在 body 里。那么就会问 POST 能不能用 URL 传值或者 URL 放一半 body 里放一半呢。经过个人测试,答案是可行的。
那么 GET 的请求呢,测试截图如下:
这里贴源码:
private Map<String, Object> params = new HashMap<>();
/**
* 功能描述:测试 PostMapping
* @param id
* @param pwd
* @return
*/
@PostMapping(value = "/v1/login")
public Object login(String id, String pwd) {
params.clear();
params.put("id", id);
params.put("pwd", pwd);
return params;
}
// 用于比较
@GetMapping(value = "/v1/login1")
public Object login1(String id, String pwd) {
params.clear();
params.put("id", id);
params.put("pwd", pwd);
return params;
}
那么 GET 怎么样才能接收到呢? 加上一个 @RequestBody()
就可接收
// 用于比较
@GetMapping(value = "/v1/login1")
public Object login1(String id, @RequestBody() String pwd) {
params.clear();
params.put("id", id);
params.put("pwd", pwd);
return params;
}
三、关于安全性
我们常听到GET不如POST安全,因为POST用body传输数据,而GET用url传输,更加容易看到。但是从攻击的角度,无论是GET还是POST都不够安全,因为HTTP本身是明文协议。每个HTTP请求和返回的每个byte都会在网络上明文传播,不管是url,header还是body。这完全不是一个“是否容易在浏览器地址栏上看到“的问题。
为了避免传输中数据被窃取,必须做从客户端到服务器的端端加密。业界的通行做法就是https——即用SSL协议协商出的密钥加密明文的http数据。这个加密的协议和HTTP协议本身相互独立。如果是利用HTTP开发公网的站点/App,要保证安全,https是最最基本的要求。
回到HTTP本身,的确GET请求的参数更倾向于放在url上,因此有更多机会被泄漏。比如携带私密信息的url会展示在地址栏上,还可以分享给第三方,就非常不安全了。此外,从客户端到服务器端,有大量的中间节点,包括网关,代理等。他们的access log通常会输出完整的url,比如nginx的默认access log就是如此。如果url上携带敏感数据,就会被记录下来。但请注意,就算私密数据在body里,也是可以被记录下来的,因此如果请求要经过不信任的公网,避免泄密的唯一手段就是https。这里说的“避免access log泄漏“仅仅是指避免可信区域中的http代理的默认行为带来的安全隐患。比如你是不太希望让自己公司的运维同学从公司主网关的log里看到用户的密码吧。
作者:大宽宽
链接:https://www.zhihu.com/question/28586791/answer/767316172
四、总结
可以把 get 和 post 当作两个不同的行为,两者并没有什么本质区别,底层都是 TCP 连接。 get请求用来从服务器上获得资源,而post是用来向服务器提交数据。比如你要获取人员列表可以用 get 请求,你需要创建一个人员可以用 post 。这也是 Restful API 最基本的一个要求。
五、参考
写的灰常详细.