HTTP协议中使用URL定位互联网上的资源,如果你需要请求这些资源就要使用相应的方法来告诉服务器你的意图,下面来看看HTTP协议中有哪些方法。
方法 | 说明 | 支持的HTTP协议版本 |
---|---|---|
GET | 获取资源 | 1.0、1.1 |
POST | 传输实体主体 | 1.0、1.1 |
PUT | 传输文件 | 1.0、1.1 |
HEAD | 获取报头首部 | 1.0、1.1 |
DELETE | 删除文件 | 1.0、1.1 |
OPTIONS | 询问支持的方法 | 1.1 |
TRACE | 追踪路径 | 1.1 |
CONNECT | 要求用隧道协议连接代理 | 1.1 |
LINK | 建立资源之间的关系 | 1.0 |
UNLINK | 断开连接关系 | 1.0 |
GET方法
GET方法用来访问已被URL识别的资源。指定的资源经过服务器解析后返回响应内容,这里为了便于理解,我们先要介绍一下URL的格式。
我们这里就不多说各个部分是什么意思了,我们把重点放在GET方法之上。如果你的方法是GET,那么服务器就会解析出你请求报头中的URL的路径,拿这个路径与自己的资源目录比较,并且返回相应的文件。从上图我们就可以看出假设使用了GET方法,那么这次客户端想请求的就是dir目录下的index.htm文件。
那么GET方法有什么特点呢?GET方法最大的特点就是通过URL传参,也就是上图中问号后面的查询字符串。正是因为通过URL传参这种特点,后面我们将他和POST方法进行对比进一步说明他们的特点。
值得强调的是,如果GET方法没有传参,那么服务器直接返回他请求的资源,如果传参,则要使用一种叫做cgi的技术进行处理。此技术我们会在后面的博客详细讲解。
POST方法
POST方法用来传输实体的主体,我们上面的GET方法也可以进行传输实体,但是由于URL长度的限定,一般都是用POST方法来传递。反过来POST也可以请求资源,但是POST的主要目的并不是获取响应的主体内容。
PUT方法
PUT方法用来传输文件。就像FTP协议文件的上传一样,要求在请求报文中包含文件的内容,然后保存在RUL指定的路径位置。PUT方法是HTTP1.1版本中才支持的方法,由于HTTP/1.1的PUT方法并不带验证的机制,任何人都可以上传文件,存在安全性的问题,因此一般的web网站不使用该方式。
HEAD方法
HEAD方法和GET方法一样,只是不返回报文的主体部分。一般用来确认URL的有效性以及资源的更新日期和时间。
DELETE方法
此方法和PUT方法刚好相反。DELETE请求方法用来删除指定的资源。这种方法比PUT方法更加没有安全性,你应该从来没有见过你能够主动删除某个网站上的资源吧,如果能,emmmm…杀个程序员祭天吧。
OPTIONS方法
OPTIONS方法用来查询针对请求URL指定的资源的支持的方法。
TRACE方法
TREACE方法是用来确认连接过程中发生的一些列操作,发送请求时在首部字段中max-forwards填入一个数值,每经过一个服务器就将该数字减一,直到该数值减为0时就停止传送,最后接到请求的服务器则返回状态码200ok的响应。
剩余的方法我们一般不常见也不常用,这里就不在过多的讲解的讲解了,而且值得注意的是,表中最后两种方式在HTTP1.1版本中已经被废弃。
经常有人吐槽说,面试官都9102年了还问get和post方法的区别,哈哈哈,其实这从侧面反应出了get和post方法的重要性,那么我们现在就一起谈一谈这俩种方法到底有什么不同之处。
不同一:安全性问题
上面我们简单提了一下GET方法是使用URL传参的,而POST方法是在报文主体中传参,这也就意味着POST在传参时更安全
如上图,如果输入密码使用了GET方法传参,那么你的密码就会被暴露在URL中,这确实是存在很大的隐患的。但是对于笔者的个人理解来看,我认为相对于GET方法来说,POST方法只能说更私密。如果知道HTTP协议特性的小伙伴一定知道,HTTP发送的数据并没有经过加密,也就是说HTTP协议发送数据就好比数据在网络上裸奔。此时就算你使用了POST方法又能怎么样,只要能截获你的报文,密码啥的都不是事。
一般使用POST方法的请求就会有报文实体部分,报文的实体部分存放的就是参数。而GET方法的请求报文则一般没有报文实体。细心的同学其实在往日使用搜索引擎时也会发现,如果使用GET方法并且有参数时,你一请求你的URL就会发生变化,而POST方法则不会发生变化。
不同二:传输的资源大小
由于传参的方式导致的另一个问题就是传输资源的大小,get方法请求由于浏览器对地址长度的限制而导致传输的数据有限制,而post方法就不会有这个问题。但是很多同学对于地址长度的限制有误解,http协议并未规定get和post的长度限制,get的最大长度限制是因为浏览器和web服务器限制了URL的长度,不同的浏览器对地址长度的限制也是不同的。要强调的是,这个长度的限制不是对于参数长度的限制,而是对于整个URL的长度。
下面是笔者找到不同的web浏览器和服务器对于get最大传参长度限制:
那么如果真的出现了get方法传参超过限制长度怎么办呢?一般浏览器或者服务器有两种解决方案,第一种是直接将URL截断,这种方式明显是有问题的。第二种方式是返回413状态码,关于413状态码的描述如下
服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下,服务器可以关闭连接以免客户端继续发送此请求。 如果这个状况是临时的,服务器应当返回一个 Retry-After 的响应头,以告知客户端可以在多少时间以后重新尝试。
不同三:传输的数据类型
相信如果有一百个人去面试,九十个人都会上面的知识,但是相信往往是那些更懂细节人才能赢得别人的青睐。这里关于传输的数据类型应该就算是一个比较边缘化的知识了。
这里要清楚的是,HTTP就如他的名字一样,因为他是基于文本的协议,所以传输时并没有以ascll码的形式传输数据,我们知道ascll码的范围是0-127。假设我们此次传输的文本是一张照片,那么关于的图片的字符编码就有可能出现127-255之间的字符,此时ascll的范围明显不适用,所以HTTP协议使用了base64编码方式。关于base64笔者在后面的博客将会为大家讲解。
所以假如你使用了GET方法,也就意味着你只能传输ascll字符,而POST方法则能够传输更多类型的数据。
不同四:速度
这里的结论是get方法的速度要比post方法更快,为什么这么说,我们一起来分析分析:
post方法的请求报文需要多处理一步:这个不难理解,因为如果是post请求的话,那么在请求报文种就会多出报文实体的部分。不过这里的影响真的微乎其微,笔者之前在写自己的HTTP服务器时,只需要根据HTTP方法来判断是否需要接着读取数据罢了,一个if就能完成的事,对于计算机来说影响不大
get会将数据缓存起来,而post不会:一般get方法请求图片等静态数据时,如果多次访问后几次的速度就会特别快,有兴趣的老铁可以进行图片的搜索,第一次有很多图片还在加载,而第二次进入则直接全部加载完毕。不过我从没见过有人使用post去请求静态数据,所以这一条特点大家作为了解就好
post不能进行管道化传输:这条对于很多人来说应该比较陌生,首先需要强调的是这种技术是基于HTTP长连接的技术,他是为了提高效率而出现的。本来对于客户端来说只有收到了上一个请求的回应才能发送下一个请求,但是对于一张需要请求多次的网页来说这种方式未免效率太低。所以此技术是把需要发送到服务器上的所有请求放到输出队列中,在第一个请求发送出去后,不等到收到服务器的应答,第二个请求紧接着就发送出去。笔者觉得这种技术有点像连续的ARQ协议,但是这种技术存在缺陷,如果一个管道中有10个连接,在发送出9个后,突然服务器告诉你,连接关闭了,此时客户端即使收到了前9个请求的答复,也会将这9个请求的内容清空,也就是说,白忙活了……此时,客户端的这9个请求需要重新发送。这对于非幂等性的POST来说存在非常大的问题,重新发送请求你就不能保证状态会发生什么样的变化,尤其是在支付时。所以一般的浏览器都不会对POST方法使用管线化技术,也就意味着请求速度绝比不上GET方法。
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响应
不同五:应用场景
post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作(淘宝,支付宝的搜索查询都是get提交),目的是资源的获取,读取数据。
关于GET和POST的不同我们就总结以上的几条,不知道小伙伴之前能够答出来几条呢,如果你只能说出来前俩条,那么你真的该给自己冲冲电了。
在谈PUT方法和POST方法之间的区别之前我们首先要清楚一个概念,就是上一小节中也提到的幂等性:幂等性可以简单的理解为同一操作执行一次,以及后续的多次执行,对系统状态的影响是一致的。
而对于上述我们所讲的方法中,GET,PUT,DELETE都是幂等操作,而POST不是。PUT请求的幂等性可以这样理解,将A修改为B,它第一次请求值变为了B,再进行多次此操作,最终的结果还是B,与一次执行的结果是一样的,所以PUT是幂等操作。 POST不是幂等操作,因为一次请求添加一份新资源,二次请求则添加了两份新资源,多次请求会产生不同的结果,因此POST不是幂等操作。
这里举个简单的例子,如果你在CSDN下发布一篇博客,使用PUT方法不管在发布时请求多少次最后都只产生一篇博客,而如果使用POST方法则可能会产生多篇相同的博客,相信不难理解,所以这也就是为什么上一小节中POST通常不会使用管线化技术的原因
关于HTTP的方法,还是要牢记各种方法的作用。并且9102还问的get和post确实是比较重要的俩个方法,一定要深入理解。PUT和POST的不同也要熟记在心,我们本篇博客提到了幂等性概念,这里给大家推荐一篇还不错的博客浅析HTTP中的幂等性。希望通过本博客让大家学到了东西。