get和post的区别

本文从HTTP报文的角度探讨GET和POST请求的区别,指出它们在传输层并无本质差异,主要区别在于参数位置和使用场景。GET用于获取信息,无副作用,可缓存,而POST用于修改数据,有副作用且不可缓存。同时,文中解答了关于GET参数写法、安全性、长度限制以及POST是否分两次发送等常见疑问。强调了安全传输应采用HTTPS而非依赖请求类型。

前言:

最近看了一些同学的面经,发现无论什么技术岗位,都这么多年了,依然还是会问有关 GET 和 POST 请求区别的问题,而搜索出来的答案并不能让我们装得一手好逼,那就让我们从 HTTP 报文的角度来撸一波,从而搞明白他们的区别。

标准答案:

注意,并不是说标准答案有误,上述区别在大部分浏览器上是存在的,因为这些浏览器实现了 HTTP 标准。

所以从标准上来看,GET 和 POST 的区别基本上可以总结如下:

  • GET 用于获取信息,无副作用,幂等,且可缓存

  • POST 用于修改服务器上的数据,有副作用,非幂等,不可缓存

但是,既然本文从报文角度来说,那就先不讨论 RFC 上的区别,单纯从数据角度谈谈。

GET和POST报文上的区别

GET 和 POST 只是 HTTP 协议中两种请求方式,而 HTTP 协议是基于 TCP/IP 的应用层协议,无论 GET 还是 POST,用的都是同一个传输层协议,所以在传输上,没有区别。

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

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

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

GET 方法简约版报文可能是这样的

GET /index.php?name=qiming.c&age=22 HTTP/1.1Host: localhost

POST 方法简约版报文可能是这样的

POST /index.php HTTP/1.1Host: localhostContent-Type: application/x-www-form-urlencoded
name=qiming.c&age=22

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

常见的疑惑问题

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

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

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

也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行,一种比较流行的写法是这样 :

http://www.example.com/user/name/yourname/age/22

二、POST 方法比 GET 方法安全?

按照网上大部分文章的解释,POST 比 GET 安全,因为数据在地址栏上不可见。

然而从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输,只要在网络节点上抓包,就能完整地获取数据报文。

要想安全传输,就只有加密,也就是 HTTPS。

三、听说 GET 方法参数长度有限制?

在网上看到很多关于两者区别的文章都有这一条,提到浏览器地址栏输入的参数是有限的。

首先说明一点,其实HTTP 协议本身倒并没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器服务器端自己限制的。

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

四、POST 方法会产生两个TCP数据包?

有些文章中提到,POST 请求会将 Header 和 Body 分开发送,先发送 Header,服务端返回 100 状态码再发送 Body。

HTTP 协议中也并没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,Header 和 Body 不会分开发送。

所以,Header 和 Body 分开发送是部分浏览器或框架的请求方法,不属于 Post的必然行为。

### HTTP GETPOST方法的区别详解 GETPOST是HTTP协议中最常用的两种请求方法,它们在功能、用途以及实现方式上存在显著差异。以下是GETPOST请求之间的主要区别: #### 1. 请求参数的传递方式 - **GET请求**:参数通过URL传递,直接显示在浏览器地址栏中。这种方式适合传输少量且非敏感的数据[^1]。 - **POST请求**:参数放在请求体(Request Body)中,不会直接显示在浏览器地址栏中。这种方式适合传输大量或敏感数据[^4]。 #### 2. 安全性 - **GET请求**:由于参数直接暴露在URL中,且会完整保留在浏览器历史记录中,因此不适合传输敏感信息[^5]。 - **POST请求**:虽然参数不直接暴露在URL中,但HTTP本身是明文传输,通过抓包工具仍可轻易获取请求体中的数据。因此,为了保证安全性,应使用HTTPS协议对数据进行加密[^2]。 #### 3. 缓存机制 - **GET请求**:会被浏览器主动缓存,除非手动设置禁用缓存。 - **POST请求**:通常不会被浏览器缓存,需要额外配置才能实现缓存。 #### 4. 数据编码方式 - **GET请求**:仅支持URL编码,所有非ASCII字符都必须在请求前进行转码。 - **POST请求**:支持多种编码方式,如application/x-www-form-urlencoded、multipart/form-data等,可以通过MIME类型传输非ASCII字符[^4]。 #### 5. 数据量限制 - **GET请求**:受URL长度限制,不同浏览器服务器对URL长度的支持有所不同,通常建议不超过2048个字符。 - **POST请求**:理论上没有长度限制,具体取决于服务器配置。 #### 6. 功能用途 - **GET请求**:主要用于获取资源,具有安全、幂等、可缓存的特点[^3]。 - **POST请求**:主要用于提交数据或更新资源,不具备幂等性,不可缓存。 #### 7. 历史记录 - **GET请求**:参数会完整保留在浏览器历史记录中[^4]。 - **POST请求**:参数不会保留在浏览器历史记录中。 #### 示例代码 以下是一个简单的GETPOST请求示例,分别使用Python的`requests`库实现: ```python import requests # GET请求示例 response_get = requests.get("https://example.com/api/data", params={"key": "value"}) print(response_get.url) # 输出完整的URL,包含参数 # POST请求示例 response_post = requests.post("https://example.com/api/data", data={"key": "value"}) print(response_post.status_code) # 输出响应状态码 ``` ### 总结 GETPOST请求在HTTP协议中有明确的分工。GET主要用于数据的获取,适合传输少量、非敏感数据;而POST主要用于数据的提交修改,适合传输大量或敏感数据。在实际开发中,正确选择请求方法不仅关系到应用的功能性,还涉及到安全性效率问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值