在面试或者笔试时,常常会被问到 HTTP 方法中 get 和 post 的异同点。本文简单整理概括了一下,以备忘。css
一些 web 相关职位的面试,不管有没有提 web,面试中的 get/post,通常就是指 web 中的 get/post。须要注意的是,web 中的 get/post 只是 http 中的 get/post 的子集,因此若是谈 get 与 post 的区别,要是面试官有心挖坑,就要特别注意下大家聊的是否是 web 中的 get/post。(本文接下去讲的 get/post 基本上是基于 web 的)html
关于 get/post,能够查看 rfc-2616 了解详情:web
其实,http 中的 get 与 post 只是单纯的名字上的区别,get 请求的数据也能够放在 request body 中,只是浏览器没有实现它,可是 get 并不仅是在 web 中使用。因此,说到 get/post 的区别,会直接条件反射地去说 web 中的 get/post 区别。而 web 中 get 以及 post,其实均可以往服务端发送数据,get 是将数据拼接在 url 上(有必要时须要 encode),而 post 是将数据封装在 request body 中,发送过去。面试
get/post 能够顾名思义地理解,get 是用来请求数据,那么,既然是请求数据,为何还要带上数据呢?其实很好理解,好比一个新闻页面,有不少内页,那么 get 请求可能带上的相似这样的参数 page=1
,即为请求第一页的数据。post 的话顾名思义就是发送数据,因此须要带上数据。ajax
何谓安全?这里的安全指的是在规范的定义下,get 操做不会修改服务器的数据,不管作多少次 get 请求,服务端的数据都是不会有变化的,因此说 get 请求是安全的。"get 请求是安全的" 换句话说就是 "get 请求不产生反作用",它仅仅是获取资源信息,就像数据库查询同样,不会修改,增长数据,不会影响资源的状态。chrome
何谓幂等?幂等是说,同一个请求原封不动的发送 N 次和 M 次(N 不等于 M,N 和 M 都大于 1),服务器上资源的状态最终是一致的,相应地服务器返回的内容也是一致的。get 请求是幂等的,由于不管请求多少次,服务器上的资源状态不变,而 post 则否则,post 会更新服务器的数据。好比发贴是非幂等的,重复 10 次发贴请求会建立 10 个帖子。但修改帖子内容是幂等的,一个修改请求重复不管多少次,帖子最终状态都是一致的。数据库
关于幂等再举个数学上的例子。对于单目运算,若是一个运算对于在范围内的全部的一个数屡次进行该运算所得的结果和进行一次该运算所得的结果是同样的,那么咱们就称该运算是幂等的。好比绝对值运算就是一个例子,在实数集中,有 abs(a)=abs(abs(a))
。这个例子很是的好,abs(a) 能够表示作了一次 get 请求后的服务器上的资源状态,对其继续作 abs 运算,状态不变,这就比如作了一次 get 请求,继续再作,而该资源状态一直不变,因此请求获得的东西也就不会变。浏览器
所以,按照某一 ID 阅览文章就是安全而幂等的,应当使用 get。而注册用户、登陆等操做会改变服务器的资源状态,不是安全而幂等的,应当使用 post。缓存
这里的 "安全",和第二点所讲的 "安全" 又是两回事了。这里的 "安全" 是密码学上的,也就是大多数场景中 "安全" 的意思。安全
其实该点很有点(post)五十步笑(get)百步之嫌。
咱们知道,get 请求是将数据附在 url 上,而 post 是将数据封装在 request body 中。因此 get 请求附加的参数可能会被人在浏览器地址栏上直接看到,或者查看一下浏览器的历史记录或者日志,就能看到你的参数。而 post 由于不能被缓存,也不能被保存为书签,因此请求过了就没有记录了?请求参数就不能被截获了?非也,抓个包就能够看到了。
因此,post 请求只是相对安全的。(防君子防不了小人)
http 协议中的 get/post 并无发送数据大小的限制,对发送数据大小产生限制的是浏览器以及操做系统、服务器,http 自己并无对 url 长度有所限制。
IE 对 URL 长度的限制是 2083字节(<=IE 8)。对于其余浏览器,如 Netscape、FireFox 等,理论上没有长度限制,其限制取决于操做系统以及服务器的支持。而 chrome 遇到长度很长的 URL 时,会直接 崩溃。
URL 长了,对服务器处理也是一种负担。本来一个会话就没有多少数据,如今若是有人恶意地构造几个几 M 大小的 URL,并不停地访问你的服务器。服务器的最大并发数显然会降低。另外一种攻击方式是,把告诉服务器 Content-Length 是一个很大的数,而后只给服务器发一点儿数据,嘿嘿,服务器你就傻等着去吧。哪怕你有超时设置,这种故意的次次访问超时也能让服务器吃不了兜着走。有鉴于此,多数服务器出于安全啦、稳定啦方面的考虑,会给 URL 长度加限制。
理论上讲,POST 是没有大小限制的,HTTP 协议规范也没有进行大小限制,说 "POST数据量存在80K/100K 的大小限制" 是不许确的,POST 数据是没有限制的,起限制做用的是服务器的处理程序的处理能力。
这点很是容易理解,打开一个页面,若是以前打开过,那么很明显速度会加快,这是由于 html/js/css/img 等文件都能被浏览器缓存(也能够被服务器缓存),而这些文件的获取,都是用的 get 请求。事实上,web 中的绝大多数请求都是用 get 完成的,post 请求目前为止我只是在 ajax 以及 form 表单中有见过。
可是实际上,http 协议中 post 和 get 都是能够被缓存的,不过不要惊讶,浏览器的实现老是比标准厉害。(post 和 get 真的只有名字上的区别啊。。)
由于 get 请求会有缓存,因此在开发过程当中,不少时候咱们要手动清除缓存,否则看不到修改后的样子。
关于 get 请求能被缓存我有个惨痛的经历。在一次开发中,要作一个跳转页面(假设为 a.index,同时须要在主页面(假设为 index.htm)中带个参数(假设为 tmp)过去,为了方便,直接将参数附加在了跳转页面的 url 上,页面地址为 a.htm?tmp,直接取其 location.search 属性便可获取参数。以后修改了 a.htm 页面的内容,可是发现一直不生效,而且已经清除了 a.htm 页面的缓存,排查了好久,缘由很显然,缓存地址为 a.htm?tmp,须要清除该地址的缓存!
因此通常要获取最新的文件(非缓存文件),能够加个相似时间戳同样的参数。
form 表单有个 method 属性,通常为 "post"。可是,其实 method 属性是能够为 "get" 的,甚至,默认就是 "get"。
若是是 "post" 方式,数据藏在 request body 中,若是是 "get" 方式,数据拼接在 url 上。可是,通常 form 表示都与 "数据提交" 相辅相成,会对服务端数据作修改,因此通常都是以 "post" 的方式。
说完 get/post,再来简单谈谈他们的其余几个好基友吧。
Http 定义了与服务器交互的不一样方法,最基本的方法有 4 种,分别是 GET,POST,PUT,DELETE。URL 全称是资源描述符,咱们能够这样认为:一个 URL 地址,它用于描述一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE 就对应着对这个资源的查,改,增,删 4 个操做。
get 和 post 成功以后应该返回 200;而 put 和 delete 在成功时则推荐使用 202.