get与post需要注意的几点

在面试或者笔试时,经常会被问到 HTTP 方法中 get 和 post 的异同点。本文简单整理归纳了一下,以备忘。

1、"get/post" VS "web 中的 get/post"

一些 web 相关职位的面试,无论有没有提 web,面试中的 get/post,一般就是指 web 中的 get/post。需要注意的是,web 中的 get/post 只是 http 中的 get/post 的子集,所以如果谈 get 与 post 的区别,要是面试官有心挖坑,就要特别注意下你们聊的是不是 web 中的 get/post。(本文接下去讲的 get/post 基本上是基于 web 的)

关于 get/post,可以查看 rfc-2616 了解详情:

其实,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 的话顾名思义就是发送数据,所以需要带上数据。

2、get 请求是安全和幂等的

何谓安全?这里的安全指的是在规范的定义下,get 操作不会修改服务器的数据,无论做多少次 get 请求,服务端的数据都是不会有变化的,所以说 get 请求是安全的。"get 请求是安全的" 换句话说就是 "get 请求不产生副作用",它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。

何谓幂等?幂等是说,同一个请求原封不动的发送 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。

3、post 相对 get 请求是 "安全" 的

这里的 "安全",和第二点所讲的 "安全" 又是两回事了。这里的 "安全" 是密码学上的,也就是大多数场景中 "安全" 的意思。

其实该点颇有点(post)五十步笑(get)百步之嫌。

我们知道,get 请求是将数据附在 url 上,而 post 是将数据封装在 request body 中。所以 get 请求附加的参数可能会被人在浏览器地址栏上直接看到,或者查看一下浏览器的历史记录或者日志,就能看到你的参数。而 post 因为不能被缓存,也不能被保存为书签,所以请求过了就没有记录了?请求参数就不能被截获了?非也,抓个包就可以看到了。

所以,post 请求只是相对安全的。(防君子防不了小人)

4、get 请求发送数据更小

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 数据是没有限制的,起限制作用的是服务器的处理程序的处理能力。

5、get 能被缓存,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,需要清除该地址的缓存!

所以一般要获取最新的文件(非缓存文件),可以加个类似时间戳一样的参数。

6、form 表单可以用 get 提交

form 表单有个 method 属性,一般为 "post"。但是,其实 method 属性是可以为 "get" 的,甚至,默认就是 "get"。

如果是 "post" 方式,数据藏在 request body 中,如果是 "get" 方式,数据拼接在 url 上。但是,一般 form 表示都与 "数据提交" 相辅相成,会对服务端数据做修改,所以一般都是以 "post" 的方式。

7、求他:put 以及 delete

说完 get/post,再来简单谈谈他们的其他几个好基友吧。

Http 定义了与服务器交互的不同方法,最基本的方法有 4 种,分别是 GET,POST,PUT,DELETE。URL 全称是资源描述符,我们可以这样认为:一个 URL 地址,它用于描述一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE 就对应着对这个资源的查,改,增,删 4 个操作。

  • GET:无副作用,幂等,不可带 Request Body
  • PUT:副作用,幂等,可以带 Request Body
  • POST:副作用,非幂等,可以带 Request Body
  • DELETE:副作用,幂等,不可带 Request Body

8、Read More

原文链接:http://www.cnblogs.com/zichi/p/5229108.html (文章来源)

随机推荐

  1. 基于Jenkins的持续交付方案

    简介 Jenkins是开源的自动化编译.测试.部署的Web应用程序一个持续性交付应用 Jenkins的优势 1.Jenkins在国内的开发者中认可度较高,很多创业公司的自建持续交付系统的选择大部分都是 ...

  2. SQL Server 2014忘记SA密码或禁用而且Windows身份验证也无法登录的解决办法

    SQL Server双重验证都无法验证的情况下如何处理 1.以管理员身份运行sql配置管理器 2.打开[Sql Server 服务]节点关掉所有服务 3.双击本地实例[SQL Server (MSSQ ...

  3. 从零开始一起学习SLAM | 学习SLAM到底需要学什么?

    SLAM涉及的知识面很广,我简单总结了 “SLAM知识树” 如下所示: (公众号菜单栏回复 “树” 可获得清晰版) 可以看到涉及的知识面还是比较广的.这里放出一张SLAM圈子里喜闻乐见的表达悲喜交加心 ...

  4. DataGrip设置长sql语句自动换行

    我这个DataGrip是英文版的. 在每个查询窗口(Console)的工具图标里,有个Settings.打开Settings弹出框,试图从Appearance和Editor里找到设置选项,却没有找到. ...

  5. 018-AJAX异步请求XMLHttpRequest

    创建XMLHttpRequest对象 一.先来创建XMLHttpRequest对象在IE.Firefox.safari和Opera中创建该对象的JavaScript代码为: var xhr = new ...

  6. JavaScript 创建和浅析自定义对象

    在Js中,除了Array.Date.Number等内置对象外,开发者可以通过Js代码创建自己的对象. 目录 1. 对象特性:描述对象的特性 2. 创建对象方式:对象直接量.new 构造函数.Objec ...

  7. Oracle与MySQL的比较[内容来自网络]

    支持的特性方面的比较: https://www.quora.com/Whats-the-difference-between-Oracle-and-MySQL oracle和mysql在 安全,数据类 ...

  8. caffe神经网络中不同的lr_policy间的区别

    lr_policy可以设置为下面这些值,相应的学习率的计算为: - fixed:  保持base_lr不变. - step:  如果设置为step,则还需要设置一个stepsize,  返回 base ...

  9. html2pdf后逐页固定位置盖公章

    需要通过NuGet添加Html2Pdf引用 #region 通过Html来生成pdf,测试Html样式 /// <summary> /// 通过Html来生成pdf,测试Html样式 // ...

  10. ECC

    素数 prime,又称为质数,是指,除了1和它本身,没有其他因数的数. 素数的定理: 1)在一个大于1的数a和它的2倍之间必定存在至少一个素数: 素数的性质: 1)在所有的大于10的质数中,个位数,只 ...