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

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

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

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

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

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

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

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

GET方法

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

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

 

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

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

比如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。

 GETPOST
后退按钮/刷新无害数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
书签可收藏为书签不可收藏为书签
缓存能被缓存不能缓存
编码类型application/x-www-form-urlencodedapplication/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、正解
(1)HTTP 协议并未规定GET和POST的请求长度限制 ;
(2)所谓的请求长度限制是由浏览器和web服务器决定和设置的。各种浏览器和web服务器的设定均不一样,这依赖于各个浏览器厂家的规定或者可以根据web服务器的处理能力来设定。IE 和 Safari 浏览器 限制 2k,Opera 限制4k,Firefox 限制 8k(非常老的版本 256byte),如果超出了最大长度,大部分的服务器直接截断,也有一些服务器会报414错误。

2、各个浏览器和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更快

1、post请求包含更多的请求头 
     因为post需要在请求的body部分包含数据,所以会多了几个数据描述部分的首部字段(如:content-type),这其实是微乎其微的。

2、最重要的一条,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更有效。但是请注意以下实际情况:
1、GET与POST都有自己的语义,不能随便混用。

2、据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。

      而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。

3、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)是不进行管道化传输的,除非手动开启!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值