get请求与post请求的区别
- get在浏览器回退时是无害的,而post会再次提交请求
- get产生的URL地址可以被bookmarks,而post不可以
- get会被浏览器主动cache,而post不会,除非手动设置
- get只能进行URL编码,而post支持多种编码方式
- get请求参数会被完整的保留在浏览器历史记录里,而post中的参数不会被保留
- get在URL中的参数是有长度限制的,而post没有
- 对于参数的类型,get只接受ASCII字符,而post没有限制
- get比post更不安全,因为参数直接暴露在URL上,所以不能传递敏感的信息
- get参数通过URL传递,post放在request body中
本质:
get和post是HTTP协议中的两种发送请求的方法。HTTP是基于TCP/IP的关于数据如果在万维网中如何通信的协议。HTTP的底层是TCP/IP,所以get和post的底层也是TCP/IP。也就是说,get和post能做的事情是一样的。你要给get加上request body或post带上URL参数,在技术上是完全行得通的。
在万维网的世界中,TCP/IP就像汽车,我们用TCP/IP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车堵在路上,整个交通系统一定会瘫痪。为了避免这种事情发生,交通规则HTTP诞生了,HTTP会给汽车运输设定了好几个服务类别,如get、post、put、delete等。HTTP规定,当执行get请求的时候,要给汽车贴上get的标签(设置method为get),而且要求把传送的数据放在车顶上(URL中)以方便记录。如果是post请求,就要在车上贴上post标签,并把货物放在车厢里。当然你也可以在get的时候在车厢中偷偷藏点货物,也可以在post的时候在车顶上放一些数据。HTTP只是个行为准则,而TCP/IP才是get和post实现的基本。
在万维网世界中,还有一个重要的角色:运输公司。不同的浏览器(发起HTTP请求)和服务器(接受HTTP请求)就是不同的运输公司。虽然理论上你可以在车顶上无限的堆货物(URL中无限加参数)。但是装卸操作是有很大成本的,所以会限制单次运输量来控制风险。数据量太大对浏览器和服务器都是很大的负担。大多数服务器最多处理64k大小的URL。如果使用get请求,在request body藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,有些服务器会直接忽略,所以get虽然可以带request body。也不能保证一定能被接收到。
get和post还有一个重大区别,简单地说:
get产生一个TCP数据包,post产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?
-
GET与POST都有自己的语义,不能随便混用。
-
据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
-
并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。