GET 和 POST 区别?网上多数答案都是错的!
最近在看《HTTP权威指南》这本书,对HTTP协议有了更深一层的了解。
在我们面试过程中关于HTTP协议有两个经典的面试题:
1. 谈谈HTTP中GET与POST的区别。
2. 在浏览器中输入URL到整个页面显示在用户面前时这个过程中到底发生了什么。
今天我就先谈谈第一个问题。
一、最普遍的答案
我们在Google或百度上搜索这个问题时,得到最多的答案就是如下三点,而这似乎也成为了“标准答案”,其实这个答案有待商榷。
1. GET使用URL或Cookie传参,而POST将数据放在BODY中。
2. GET方式提交的数据有长度限制,则POST的数据则可以非常大。
3. POST比GET安全,因为数据在地址栏上不可见。
二、“标准答案”其实是错的
1. GET使用URL或Cookie传参,而POST将数据放在BODY中
GET和POST是由HTTP协议定义的。在HTTP协议中,Method和Data(URL, Body, Header)是正交的两个概念,也就是说,使用哪个Method与应用层的数据如何传输是没有相互关系的。
HTTP没有要求,如果Method是POST数据就要放在BODY中。也没有要求,如果Method是GET,数据(参数)就一定要放在URL中而不能放在BODY中。
那么,网上流传甚广的这个说法是从何而来的呢?我在HTML标准中,找到了相似的描述。这和网上流传的说法一致。但是这只是HTML标准对HTTP协议的用法的约定。怎么能当成GET和POST的区别呢?
而且,现代的Web Server都是支持GET中包含BODY这样的请求。虽然这种请求不可能从浏览器发出,但是现在的Web Server又不是只给浏览器用,已经完全地超出了HTML服务器的范畴了。
2. GET方式提交的数据有长度限制,则POST的数据则可以非常大
先说结论:HTTP协议对GET和POST都没有对长度的限制。HTTP协议明确地指出了,HTTP头和Body都没有长度的要求。
首先是"GET方式提交的数据有长度限制",如果我们使用GET通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了。而实际上,URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
注意这个限制是整个URL长度,而不仅仅是你的参数值数据长度。
POST也是一样,POST是没有大小限制的,HTTP协议规范也没有对POST数据进行大小限制,起限制作用的是服务器的处理程序的处理能力。
当然,我们常说GET的URL会有长度上的限制这个说法是怎么回事呢?虽然这个不是GET和POST的本质区别,但是我们也可以说说导致URL长度限制的两方面的原因:
1. 浏览器。早期的浏览器会对URL长度做限制。而现在的具体限制是怎么样的,我自己没有亲测过,就不复制网上的说法啦。
2. 服务器。URL长了,对服务器处理也是一种负担。原本一个会话就没有多少数据,现在如果有人恶意地构造几个M大小的URL,并不停地访问你的服务器。服务器的最大并发数显然会下降。另一种攻击方式是,告诉服务器Content-Length是一个很大的数,然后只给服务器发一点儿数据,服务器你就傻等着去吧。哪怕你有超时设置,这种故意的次次访问超时也能让服务器吃不了兜着走。有鉴于此,多数服务器出于安全啦、稳定啦方面的考虑,会给URL长度加限制。但是这个限制是针对所有HTTP请求的,与GET、POST没有关系。
3. POST比GET安全,因为数据在地址栏上不可见
这个说法其实也是基于上面的1,2两点的基础上来说的,我觉得没什么问题,但是需要明白为什么使用GET在地址栏上就不安全了,以及还有没有其他原因说明“POST比GET安全”。
通过GET提交数据,用户名和密码将明文出现在URL上,因为登录页面有可能被浏览器缓存,其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击。
三、我的理解
“1. GET使用URL或Cookie传参,而POST将数据放在BODY中”,这个是因为HTTP协议用法的约定。并非它们的本身区别。
“2. GET方式提交的数据有长度限制,则POST的数据则可以非常大”,这个是因为它们使用的操作系统和浏览器设置的不同引起的区别。也不是GET和POST本身的区别。
“3. POST比GET安全,因为数据在地址栏上不可见”,这个说法没毛病,但依然不是GET和POST本身的区别。
虽然这三点不是它们的本身区别,但至少是它们在使用上的区别,所以我在面试这个问题时,如果面试者能够回答上面三点我基本会给个及格分。那么你想不想要更高的分数?
四、终极区别
GET和POST最大的区别主要是GET请求是幂等性的,POST请求不是。这个是它们本质区别,上面的只是在使用上的区别。
什么是幂等性?幂等性是指一次和多次请求某一个资源应该具有同样的副作用。简单来说意味着对同一URL的多个请求应该返回同样的结果。
关于幂等性看我评论上推荐的一篇文章。
正因为它们有这样的区别,所以不应该且不能用get请求做数据的增删改这些有副作用的操作。因为get请求是幂等的,在网络不好的隧道中会尝试重试。如果用get请求增数据,会有重复操作的风险,而这种重复操作可能会导致副作用(浏览器和操作系统并不知道你会用get请求去做增操作)。
你是一位道具师,演员在拍电影时大家都约定俗成在对打时用假抢(无杀伤力),在打靶时用气枪(有杀伤力),而你是个异类的道具师,你在对打时把演员的假抢换成了气枪...
五、我的建议
如果面试官问你这个问题时,我建议你说出上面三点,同时要说明那三点是它们在使用上的区别,当然也要把它们的终极区别给说出来。
PS:曾经有一个研读了HTTP协议的人去一家公司面试,面试官问他这个问题时,他回答“GET是用于获取数据的,POST一般用于将数据发给服务器。其他GET和POST没什么区别”,于是被刷了。
因为有些面试官心中也只有那一个“标准答案”。
GET 和 POST 区别?网上多数答案都是错的!的更多相关文章
- GET和POST有什么区别?及为什么网上多数答案都是错的(转载)
这仅仅是我认为比较好的关于get和post区别的解答,然后把作者的一些文字踢除留下比较干的部分. 作者:南柯之石链接:http://www.cnblogs.com/nankezhishi/archiv ...
- GET和POST有什么区别?及为什么网上的多数答案都是错的
如果有人问你,GET和POST,有什么区别?你会如何回答? 最普遍的答案 回来之后寻思了很久,他到底是想问我什么?我一直就觉得GET和POST没有什么除了语义之外的区别,自打我开始学习Web编程开始就 ...
- (OPC Client .NET 开发类库)网上很多网友都有提过,.NET开发OPC Client不外乎下面三种方法
1. 背景 OPC Data Access 规范是基于COM/DCOM定义的,因此大多数的OPC DA Server和client都是基于C++开发的,因为C++对COM/DCOM有最好的支持.现在, ...
- npm权限不够(安装什么都报错)
问题 Windows下使用npm安装任何包都报错, Windows下使用npm显示权限不够 如图: 解决方法 1. 方法一 使用管理员权限打开 命令窗口, 治标不治本!!!!不推荐 ...
- Idea破解办法+idea免费生成注册码+jsp属性选择器+注解什么的都报错
Idea破解办法: http://blog.csdn.net/bitcarmanlee/article/details/54951589 idea免费生成注册码: http://idea.iteblo ...
- 号外,号外 -几乎所有的binary search和mergesort都有错
号外,号外 -几乎所有的binary search和mergesort都有错 这是Joshua Bloch(Effective Java的作者)在google blog上发的帖子.在说这个帖子之前,不 ...
- 【EWM系列】SAP EWM模块-修改任何内容都报错
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[EWM系列]SAP EWM模块-修改任何内容都 ...
- IC卡和RFID卡的区别(网上说的都不准确)
其实IC卡是卡类型的称呼,IC卡和RFID卡不应该在一起对比的,和IC卡在一起对比的应该是ID卡. RFID卡是其实是对卡技术类型称呼. IC为卡类型称呼(Integrated Circuit Car ...
- UVA 10603 Fill(正确代码尽管非常搓,网上很多代码都不能AC)
题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=1544">click here~ ...
随机推荐
- @InitBinder的作用
由@InitBinder表示的方法,可以对WebDataBinder对象进行初始化.WebDataBinder是DataBinder的子类,用于完成由表单到JavaBean属性的绑定. @InitBi ...
- Ubuntu下查看so文件的函数列表
Ubuntu下查看so文件的函数列表 可使用如下命令: 1.nm -D XXX.so 2.objdump -tT XXX.so nm libcyusb.so | grep "usb ...
- 19.8.8 flutter 学习之创建第一个可变的Widget
创建一个很简单的可变的Widget 效果就是点击字的时候会变化 完整代码: class CarPage extends StatefulWidget { @override _CarState cre ...
- HDU - 6396 Swordsman (单调性+贪心)
题意:有n个怪物和k种属性,当且仅当你的每种属性都大于等于怪物的属性才可以击杀它,且击杀怪物可以提升你一定的属性值.求可击杀怪物的最大数量以最终的属性值. 这不就是银行家算法里的安全性检验么? 本题的 ...
- centos7中使用yum安装tomcat mysql 等
安装Tomcat 进入 # cd /usr/local/tomcat # wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7 ...
- hive的外部表
最近买了一本hive看,发现书中有一个错误: 我的验证如下: 1.外部表数据存在自己表所属的目录下 2.还发现了 CTAS 操作不能 建立外部表
- LightOJ-1079-Just another Robbery(概率, 背包)
链接: https://vjudge.net/problem/LightOJ-1079#author=feng990608 题意: As Harry Potter series is over, Ha ...
- LINUX笔记之二常用命令(权限管理命令)
1. +增加权限:-去掉权限:=直接赋权. r(4)w(2)x(1) 重点掌握:通过数字授权,例如rxwr-xr--是754 例题:用root用户创建目录并在此目录新建文件,之后更改新文件的权限为77 ...
- ORACLE/SQL用函数进行每年,每月,每周,每日的数据汇总
15/03/21 用函数进行每年,每月,每周,每日的数据汇总 假设一个销售明细表 sale_detail 含有 国家(country),销售时间(sale_time),销售额(sale_money) ...
- HDU 3480 Division DP斜率优化
解题思路 第一步显然是将原数组排序嘛--然后分成一些不相交的子集,这样显然最小.重点是怎么分. 首先,我们写出一个最暴力的\(DP\): 我们令$F[ i ][ j ] $ 为到第\(i\)位,分成\ ...