HTTP 中 GET 与 POST 的区别

GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二。

最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。

你可能自己写过无数个GET和POST请求,或者已经看过很多权威网站总结出的他们的区别,你非常清楚知道什么时候该用什么。你轻轻松松的给出了一个“标准答案”:

  • GET在浏览器回退时是无害的,而POST会再次提交请求。

  • GET产生的URL地址可以被Bookmark,而POST不可以。

  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。

  • GET请求只能进行url编码,而POST支持多种编码方式。

  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

  • GET请求在URL中传送的参数是有长度限制的,而POST么有。

  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

  • GET参数通过URL传递,POST放在Request body中。

请告诉我真相。。。 

如果我告诉你GET和POST本质上没有区别你信吗? 

GET和POST是什么?HTTP协议中的两种发送请求的方法。

HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。

HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。 

(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。

好了,现在你知道,GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。 

GET 和 POST 报文上的区别

先下结论,GET 和 POST 方法没有实质区别,只是报文格式不同。

报文格式上,不带参数时,最大区别就是第一行方法名不同

  • POST 方法请求报文第一行是这样的 POST /uri HTTP/1.1 \r\n
  • GET 方法请求报文第一行是这样的 GET /uri HTTP/1.1 \r\n

是的,不带参数时他们的区别就仅仅是报文的前几个字符不同而已

带参数时报文的区别呢? 在约定中,GET 方法的参数应该放在 url 中,POST 方法参数应该放在 body 中

举个例子,如果参数是 name=qiming.c, age=22。

  • GET 方法简约版报文是这样的
GET /index.php?name=qiming.c&age=22 HTTP/1.1
Host: localhost
  • POST 方法简约版报文是这样的
POST /index.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

name=qiming.c&age=22

现在我们知道了两种方法本质上是 TCP 连接,没有差别,也就是说,如果我不按规范来也是可以的。我们可以在 URL 上写参数,然后方法使用 POST;也可以在 Body 写参数,然后方法使用 GET。当然,这需要服务端支持。

GET的参数

一、GET 方法参数写法是固定的吗?

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

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

也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行,

二、GET请求中URL编码的意义

在GET请求中会对URL中非西文字符进行编码,这样做的目的就是为了 避免歧义

可以用python3自带的库来完成:

>>> from urllib.parse import urlencode
>>> data = {
... 'country':'中国',
... 'language':'汉语'
... }
>>> urlencode(data)
'country=%E4%B8%AD%E5%9B%BD&language=%E6%B1%89%E8%AF%AD'

如果只想对一个字符串进行urlencode转换,urllib提供另外一个函数:quote()

>>> from urllib.parse import quote, unquote
>>> quote('中国')
'%E4%B8%AD%E5%9B%BD'
>>> unquote('%E4%B8%AD%E5%9B%BD')
'中国'

 

 

参考链接:

1. https://www.oschina.net/news/77354/http-get-post-different?p=6

2. https://blog.fundebug.com/2019/02/22/compare-http-method-get-and-post/

3. https://blog.csdn.net/justloveyou_/article/details/78303617

4. https://blog.csdn.net/haoni123321/article/details/15814111

posted @ 2019-11-20 22:06  Rogn  阅读(538)  评论(0编辑  收藏  举报