超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通讯。html
HTTP 的工做方式是客户机与服务器之间的请求-应答协议。web
web 浏览器多是客户端,而计算机上的网络应用程序也可能做为服务器端。ajax
举例:客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。响应包含关于请求的状态信息以及可能被请求的内容。chrome
在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。浏览器
查询字符串(名称/值对)是在 GET 请求的 URL 中发送的。缓存
/test/demo_form.asp.net?name1=value1&name2=value2安全
在约定中,参数是写在 ? 后面,用 & 分割。服务器
解析报文的过程是经过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。cookie
好比header请求头中添加token,来验证用户是否登陆等权限问题。网络
也就是说,能够本身约定参数的写法,只要服务端可以解释出来就行,万变不离其宗。
应用场景:
能够看到有General 、Response Headers、Request Headers。
有关 GET 请求的其余一些注释:
查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的。
POST /test/demo_form.asp.net HTTP/1.1 Host: baidu.com name1=value1&name2=value2
应用场景:
能够看到POST请求中多了Form Data(body中的一种表单请求类型)。
有关 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 只是 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怎么实现的基本。
一、正解
(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 长度加限制。
一、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 必然行为。
GET请求参数是在URL后面的,数据在地址栏上可见;POST请求参数放在请求体重,数据在地址栏上不可见,所以有人说POST 比 GET 安全。
然而,从传输的角度来讲,他们都是不安全的,由于 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。
要想安全传输,就只有加密,也就是 HTTPS。
是否缓存数据,不一样的浏览器厂商的实现方式不同。
《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)是不进行管道化传输的,除非手动开启!