也谈 GET 和 POST 的区别

标签: get post | 发表时间:2012-07-27 20:06 | 作者:鹤冲天
出处:http://www.cnblogs.com/

上个月,博客园精华区有篇文章《 GET 和 POST 有什么区别?及为什么网上的多数答案都是错的 》,文中和回复多是对以下两个问题进行了深究:

  • 长度限制
  • Url 是否隐藏数据

在我看来这两者都不是重点,特写此文予以讨论。

我们先来看些基本概念:

HTTP 基本概念

HTTP Request Methods

GET、POST 专业名称是 HTTP Request Methods。但 HTTP Request Methods 不只是 GET 和 POST,完整列表如下:

  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • OPTIONS
  • TRACE
  • CONNECT
  • PATCH

REST 使用前四个:GET、POST、PUT、DELETE。因些这四个也是经常被一块提及的,将这四个作为关键字进行搜索,你会得到更深入的结果。

在一般的 Web 开发中,GET 和 POST 用得最多,网上对这两的讨论也是最多,往往又很肤浅的。

更多信息请查看:

    http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

    http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

    http://zh.wikipedia.org/wiki/REST

Safe Methods(安全方法)

RFC 2616 中定义如下(后面有翻译):

Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

网址: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1

维基百科中的说明(对 RFC 2616翻译):

开发者应当意识到他们的 软件代表了用户在 因特网上进行交互,并且应当告知用户,他们正在进行的操作可能对他们自身或者其他人有未曾预料的重要影响。

特别地,对于GET和HEAD方法而言,除了进行获取资源信息外,这些请求不应当再有任何其他意义。也就是说,这些方法应当被认为是“安全的”。客户端应当使用其他“非安全”方法,例如POST,PUT及DELETE来以特殊的方式(通常是按钮而不是 超链接)使得客户能够意识到可能要负的责任(例如一个按钮带来的资金交易)或者被告知正在请求的操作可能是不安全的(例如某个文件将被上传或删除)。

但是,不能想当然地认为服务器在处理某个GET请求时不会产生任何副作用。事实上,很多动态资源会把这作为其特性。这里重要的区别在于用户并没有请求这一副作用,因此不应由用户为这些副作用承担责任。

来源网址: http://zh.wikipedia.org/wiki/超文本传输协议#.E5.AE.89.E5.85.A8.E6.96.B9.E6.B3.95

这部分读起来比较晦涩,不要着急,读完后面的再回头看就好理解了。

GET 与 POST 的区别

综上所述,可总结如下:

  • GET 仅用来获取查看信息,不能改变服务器信息。
  • POST 用来改变服务器信息。

这里说的改变,包括增加、修改和删除。

这是 HTTP 协议中的要求,众多浏览器和浏览器插件都遵守这些约定。如果你的代码不按照这约定来,可能会出现严重的后果。

使用 GET 改变服务器信息的严重后果

假定你编写的 Web 程序或网站允许 GET 提交的修改,比如允许用户通过以下 Url 直接删除编写为 1024 的订单:

   ~/orders/delete/1024

那么在订单的管理(或列表)页面,你可能会定义一个删除连接如下:

    <a href="/orders/delete/1024">删除</a>

当然不会这么简单,一般都会在删除之前会提示用户一下,加上确认提示脚本:

    <a href="/orders/delete/1024" onclick="return confirm('确实要删除吗?')">删除</a>

(说明:我在这里只是示简单例下,添加确认删除还是建议使用 Unobtrusive JavaScript 方式,可以使用 jQuery。)

很多开发人员以为这样就万事大吉了,有了确认提示,也不怕误删。但问题就恰恰出在这里,2005年时,谷歌发布了一款浏览器加速插件:Google Web Accelerator(以下简称 GWA),让这种问题严重的暴露了出来。

GWA 通过多种技术来加速,其中一种就是页面预先加载:比如你在查看我这篇文章的时候,GWA 可能把我前一篇或其它文章预先在后台下载,这样你在点击时,就节省了时间,起到了加速的效果。

GWA 的预先加载是根据当前页面中的链接来的,根据 HTTP 的协议,点击链接时使用 GET 方法获取信息,因些不会对服务器造成影响。因此 GWA 会放心的加载当前页面链接对应的网页。当然也可能会加速上面提到的订单删除链接,GWA 会无视你的确认删除脚本,直接从后台把 "/orders/delete/1024" 载入,也就意味着 1024 订单已经被删除了。

GWA 发布后,很多网站出现了很多莫名其妙的问题,数据无故丢失,商品自动加入了用户的购物车,用户无端地被扣款…

一时问题很严重,后来发现的原因的所在,就是网站开发者没有遵守 HTTP 约定,没有弄明白 GET 和 POST 的区别。

可以查看以下文章深入了解这段历史:

    http://blogs.adobe.com/cantrell/archives/2005/06/what_have_we_le.html

    http://blog.moertel.com/articles/2005/05/06/google-web-accelerator-offers-web-developers-an-important-opportunity

而如今,谷歌发布的 Chrome 浏览器,类似的加速功能集成了进去,你可以在 设置 - 显示高级设置 里面看得到:

image

所以,对服务器有改变的一定要用 POST,GWA 和类似的插件不会提交 POST 表单加速的。

删除、查看用户信息收费(比如人才网、婚恋网)、加入购物车等操作还是放在 POST 表单中用 Button 来吧。

再回头读维基百科中对 Safe Methods 的说明,相信你会明白很多。

注意:但也不是所有对服务器有改变的都要用 POST,比如你点击本文下面的 前一篇博文链接 ,我的文章访问量可能+1,对服务器有所改变,但这种改变是轻微的,影响不大(相对删除、扣款来说),可以放心的使用链接(GET 方式)。

基它一些区别:

  • 使用 GET 表单查询,查询结果页面可以收藏;POST 表单不行。
  • 向服务器发送文件只能使用 POST 表单。

能想到的大致这些吧。

感言

之前,我曾学习 ASP.NET 多年,但对 HTTP 几乎一无所知,WebForm 封装了一切:

  • 不用去考虑 POST、GET,只需知道 Postback;
  • 不用多考虑值来回传递,因为有 ViewState;
  • 不用关心 Html,因为有服务端控件。

更悲哀的是,我有很长一段时间都认为一个页面上只能有一个 Form。

后来做了一段时间 WinForm 后,开始学习 ASP.NET MVC,开始逐步了解 Html、Http 等等,也开始知道了 Post-Redirect-Get 模式等等。

看到很多人浅浅讨论 GET 和 POST,感到很无奈,WebForm 误人啊。要想进步,还是学学 ASP.NET MVC 吧!

 

(本人知识有限,如文中有错误或不妥之处,请指正,非常感谢!)

本文链接

相关 [get post] 推荐:

从HTTP GET和POST的区别说起

- jin - Yining.write()
在推特上抱怨面试时问HTTP GETE和POST的区别得到回答都不满意,有人不清楚,当时只回复了看 RFC2616. 面试时得到的回答大多是:POST是安全的,因为被提交的数据看不到,或者被加密的,其它的还有GET的时候中文出现乱码(在地址栏里),数据最大长度限制等等. 说 POST 比 GET 安全肯定是错的,POST跟GET都是明文传输,用httpfox等插件,或者像WireShark 等类似工具就能观察到.

也谈 GET 和 POST 的区别

- - 博客园_首页
上个月,博客园精华区有篇文章《 GET 和 POST 有什么区别. 及为什么网上的多数答案都是错的 》,文中和回复多是对以下两个问题进行了深究:. 在我看来这两者都不是重点,特写此文予以讨论. GET、POST 专业名称是 HTTP Request Methods. 但 HTTP Request Methods 不只是 GET 和 POST,完整列表如下:.

GET和POST有什么区别?

- - 博客园_知识库
  如果有人问你, GET 和POST ,有什么区别. 我说GET是用于获取数据的,POST,一般用于将数据发给服务器之用.   这个答案好像并不是他想要的. 我说这就是个名字而已,如果服务器支持,他完全可以把GET改个名字叫GET2. 他反问道,那就是单纯的名字上的区别喽. 我想了想,我觉得如果说再具体的区别,只能去看RFC文档了,还 要取决于服务器(指 Apache ,IIS )的具体实现.

浅谈http中get和post的区别

- - Web前端 - ITeye博客
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE. URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作. 到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息.

HttpUrlconnection 、Httpclient get 、post 请求核心代码

- - CSDN博客推荐文章
HttpURLConnection的使用  . * URL请求的类别分为二类,GET与POST请求. * a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet, . * b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内.

fred: 使用 NodeJS + Express 從 GET/POST Request 取值

- - Planet DebianTW
過去無論哪一種網站應用程式的開發語言,初學者教學中第一次會提到的起手式,八九不離十就是 GET/POST Request 的取值. 但是,在 Node.js + Express 的世界中,彷彿人人是高手,天生就會使用,從不曾看到有人撰文說明. 這應該算是開發 Web Service 的入門,在 Client 與 Server 的互動中,瀏覽器發出 GET/POST Request 時會傳值給 Server-side,常見應用就是網頁上以 POST method 送出的表單內容,或是網址列上的 Query Strings (ex: page?page=3&id=5).

java给微信发送get和post请求

- - CSDN博客推荐文章
现在做微信订阅号、微信公众号,微信企业号都需要开发者给微信服务器发送get或post请求. 具体发送get或post请求源码如下:. * 向指定URL发送GET方法的请求. 请求参数,请求参数应该是 name1=value1&name2=value2 的形式. * @return URL 所代表远程资源的响应结果.

为什么要禁止除GET和POST之外的HTTP方法?

- - FreeBuf互联网安全新媒体平台 | 关注黑客与极客
最近老是听朋友说,被上级单位通报HTTP不安全方法漏洞,本来是低危漏洞,也没怎么注意它,最近升为中危漏洞,每天催着去整改,闹得人心惶惶,甚至经常被维护人员吐槽,做的是得不偿失的事情. 因此,有必要说明一下,为什么要禁止除GET和POST之外的HTTP方法. 换句话说,对于 这些HTTP不安全方法,到底有多不安全呢.

[译] 99% 的人都理解错了 HTTP 中 GET 与 POST 的区别

- - IT瘾-tuicool
作者:WebTechGarden. GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己写过无数个GET和POST请求,或者已经看过很多权威网站总结出的他们的区别,你非常清楚知道什么时候该用什么.

iframe post提交数据

- - Web前端 - ITeye博客
对于iframe默认get提交 需要进行post数据的大量提交,给找到外国网站的简单例子如:
. 因为我项目用到的是 页面用的tab 样式(如何实现tab样式切换这里不做说明),嵌入的是三个页面iframe,需要在切换的时候更改target指定iframe名字,为了验证是否可行,只好试下,不然无别的办法.