C# HTTP系列8 GET与POST对比说明

  HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通讯的规则,经过因特网传送万维网文档的数据传送协议。

超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通讯。html

HTTP 的工做方式是客户机与服务器之间的请求-应答协议。web

web 浏览器多是客户端,而计算机上的网络应用程序也可能做为服务器端。ajax

举例:客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。响应包含关于请求的状态信息以及可能被请求的内容。chrome

在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。浏览器

  • GET - 从指定的资源请求数据。
  • POST - 向指定的资源提交要被处理的数据
GET方法

查询字符串(名称/值对)是在 GET 请求的 URL 中发送的缓存

/test/demo_form.asp.net?name1=value1&name2=value2安全

 

在约定中,参数是写在 ? 后面,用 & 分割。服务器

解析报文的过程是经过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。cookie

好比header请求头中添加token,来验证用户是否登陆等权限问题。网络

也就是说,能够本身约定参数的写法,只要服务端可以解释出来就行,万变不离其宗。

应用场景:

能够看到有General 、Response Headers、Request Headers。

有关 GET 请求的其余一些注释:

  • GET 请求可被缓存
  • GET 请求保留在浏览器历史记录中
  • GET 请求可被收藏为书签
  • GET 请求不该在处理敏感数据时使用
  • GET 请求有长度限制
  • GET 请求只应当用于取回数据
POST方法

查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的

POST /test/demo_form.asp.net HTTP/1.1
Host: baidu.com
name1=value1&name2=value2

应用场景:

能够看到POST请求中多了Form Data(body中的一种表单请求类型)。

  • headers:主要存放cookie等其余信息
  • body:主要存放POST的一些数据,如username:xxx

有关 POST 请求的其余一些注释:

  • POST 请求不会被缓存
  • POST 请求不会保留在浏览器历史记录中
  • POST 不能被收藏为书签
  • POST 请求对数据长度没有要求
GET 与 POST 比较

下面的表格比较了两种 HTTP 方法:GET 和 POST。

  GET POST
后退按钮/刷新 无害 数据会被从新提交(浏览器应该告知用户数据会被从新提交)。
书签 可收藏为书签 不可收藏为书签
缓存 能被缓存 不能缓存
编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。
历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。
对数据长度的限制 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 无限制。
对数据类型的限制 只容许 ASCII 字符。 没有限制。也容许二进制数据。
安全性

与 POST 相比,GET 的安全性较差,由于所发送的数据是 URL 的一部分。

在发送密码或其余敏感信息时毫不要使用 GET !

POST 比 GET 更安全,由于参数不会被保存在浏览器历史或 web 服务器日志中。
可见性 数据在 URL 中对全部人都是可见的。 数据不会显示在 URL 中。
 

HTTP请求方法

HTTP请求,最初设定了八种方法。这八种方法本质上没有任何区别。只是让请求更加有语义而已。

下面的表格列出了其余一些 HTTP 请求方法。

方法 描述
OPTIONS 返回服务器支持的 HTTP 请求方法。
GET 向服务器获取指定资源。参数放在URL后面。
HEAD 与 GET 相同,但只返回 HTTP 报头,不返回文档主体。
POST 向服务器提交数据,数据放在请求体里。
PUT

上传指定的 URI 表示。

与POST类似,只是具备幂等特性,通常用于更新。

DELETE 删除服务器上的指定资源。
TRACE 回显服务器端收到的请求,测试的时候会用到这个。
CONNECT 把请求链接转换到透明的 TCP/IP 通道。
 
GET 与 POST 本质区别
从标准上来看,GET 和 POST 的区别以下:
  • GET 用于获取信息,是无反作用的,是幂等的,且可缓存;
  • POST 用于修改服务器上的数据,有反作用,非幂等,不可缓存。

从请求报文上来看,GET、POST的区别以下:

GET 和 POST 只是 HTTP 协议中两种请求方式(殊途同归),而 HTTP 协议是基于 TCP/IP 的应用层协议,不管 GET 仍是 POST,用的都是同一个传输层协议,因此在传输上,没有任何区别。

若是你要给GET加上request body,技术上是彻底行的通的。

 

若是你要给给POST带上url参数,技术上也是彻底行的通的。

可是尽可能不要这么作,请按照 GET 与 POST 的标准要求去传递请求参数。

在万维网世界中,TCP就像汽车,咱们用TCP来运输数据,它很可靠,历来不会发生丢件少件的现象。可是若是路上跑的全是看起来如出一辙的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统必定会瘫痪。为了不这种状况发生,交通规则HTTP诞生了。

HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),并且要求把传送的数据放在车顶上(url中)以方便记录。若是是POST请求,就要在车上贴上POST的标签,并把货物放在车箱里。固然,你也能够在GET的时候往车箱内偷偷藏点货物,可是这是很不光彩;也能够在POST的时候在车顶上也放一些数据,让人以为傻乎乎的。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。

GET传参最大长度的理解
HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大可能是浏览器和服务器的缘由。

一、正解
(1)HTTP 协议并未规定GET和POST的请求长度限制 ;
(2)所谓的请求长度限制是由浏览器和web服务器决定和设置的。各类浏览器和web服务器的设定均不同,这依赖于各个浏览器厂家的规定或者能够根据web服务器的处理能力来设定。IE 和 Safari 浏览器 限制 2k,Opera 限制4k,Firefox 限制 8k(很是老的版本 256byte),若是超出了最大长度,大部分的服务器直接截断,也有一些服务器会报414错误。

二、各个浏览器和web服务器的最大长度总结 
浏览器 
(1)IE:IE浏览器(Microsoft Internet Explorer) 对url长度限制是2083(2K+53),超过这个限制,则自动截断(如果form提交则提交按钮不起做用)。 
(2)Firefox:火狐浏览器的url长度限制为 65536字符,但实际上有效的URL最大长度很多于100,000个字符。 
(3)Chrome:谷歌浏览的url长度限制超过8182个字符返回本文开头时列出的错误。 
(4)Safari:Safari的url长度限制至少为 80 000 字符。 
(5)Opera:Opera 浏览器的url长度限制为190 000 字符。Opera9 地址栏中输入190000字符时依然能正常编辑。 


服务器 
(1)Apache:Apache能接受url长度限制为8 192 字符 
(2)IIS:Microsoft Internet Information Server(IIS)能接受url长度限制为16384个字符。这个是能够经过修改的(IIS7) 
                configuration/system.webServer/security/requestFiltering/requestLimits@maxQueryStringsetting.

服务器是由于处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。

为何GET比POST更快

一、post请求包含更多的请求头 
     由于post须要在请求的body部分包含数据,因此会多了几个数据描述部分的首部字段(如:content-type),这实际上是微乎其微的。

二、最重要的一条,post在真正接收数据以前会先将请求头发送给服务器进行确认,而后才真正发送数据 
post请求的过程: 
(1)浏览器请求tcp链接(第一次握手); 
(2)服务器答应进行tcp链接(第二次握手); 
(3)浏览器确认,并发送post请求头(第三次握手,这个报文比较小,因此http会在此时进行第一次数据发送) ;
(4)服务器返回100 Continue响应 ;
(5)浏览器发送数据; 
(6)服务器返回200 OK响应。

get请求的过程: 
(1)浏览器请求tcp链接(第一次握手); 
(2)服务器答应进行tcp链接(第二次握手); 
(3)浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,因此http会在此时进行第一次数据发送) 
(4)服务器返回200 OK响应 。
也就是说,目测get的总耗是post的2/3左右,已经有网友进行过相关的测试。

数据包

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,某些厂商的浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

由于POST须要两步,时间上消耗的要多一点,看起来GET比POST更有效。可是请注意如下实际状况:
一、GET与POST都有本身的语义,不能随便混用。

二、据研究,在网络环境好的状况下,发一次包的时间和发两次包的时间差异基本能够无视。

      而在网络环境差的状况下,两次包的TCP在验证数据包完整性上,有很是大的优势。

三、HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包。
      并非全部浏览器都会在POST中发送两次包。
      并且实际测试(Chrome、Firefox)发现就只发送一次,header 和 body 不会分开发送。

      因此,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。

POST 方法比 GET 方法安全?【误解】

GET请求参数是在URL后面的,数据在地址栏上可见;POST请求参数放在请求体重,数据在地址栏上不可见,所以有人说POST 比 GET 安全。
然而,从传输的角度来讲,他们都是不安全的,由于 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。
要想安全传输,就只有加密,也就是 HTTPS。

GET 会将数据缓存起来,而POST不会 ?【误解】
经测试,使用ajax采用GET方式请求静态数据(好比html页面,图片)的时候,若是两次传输的数据相同,第二次之后消耗的时间将会在10ms之内(chrome测试),而POST每次消耗的时间都差很少。经测试,chrome和firefox下若是检测到GET请求的是静态资源,则会缓存,若是是数据,则不会缓存,可是IE什么都会缓存起来。

是否缓存数据,不一样的浏览器厂商的实现方式不同。

POST不能进行管道化传输 

《HTTP权威指南》中是这样说的:http的一次会话须要先创建tcp链接(大部分是tcp,可是其余安全协议也是能够的),而后才能通讯,若是 每次链接都只进行一次http会话,那这个链接过程占的比例太大了!因而出现了持久链接:在http/1.0+中是connection首部中添加keep-alive值,在http/1.1中是在connection首部中添加persistent值,固然二者不只仅是命名上的差异,http/1.1中,持久链接是默认的,除非显示在connection中添加close,不然持久链接不会关闭,而http/1.0+中则刚好相反,除非显示在connection首部中添加keep-alive,不然在接收数据包后链接就断开了。
  出现了持久链接还不够,在http/1.1中,还有一种称为管道通讯的方式进行速度优化:把须要发送到服务器上的全部请求放到输出队列中,在第一个请求发送出去后,不等到收到服务器的应答,第二个请求紧接着就发送出去,可是这样的方式有一个问题:不安全,若是一个管道中有10个链接,在发送出9个后,忽然服务器告诉你,链接关闭了,此时客户端即便收到了前9个请求的答复,也会将这9个请求的内容清空,也就是说,白忙活了……此时,客户端的这9个请求须要从新发送。这对于幂等请求还好(好比get,多发送几回都不要紧,每次都是相同的结果),若是是post这样的非幂等请求(好比支付的时候,多发送几回就惨了),确定是行不通的。
  因此,post请求不能经过管道的方式进行通讯!颇有可能,post请求须要从新创建链接,这个过程不跟彻底没优化的时候同样了么?因此,在可使用get请求通讯的时候,不要使用post请求,这样用户体验会更好,固然,若是有安全性要求的话,post会更好。管道化传输在浏览器端的实现还需考证,貌似默认状况下大部分浏览器(除了opera)是不进行管道化传输的,除非手动开启!

 

相关文章
相关标签/搜索