Get和Post
# Get和Post
GET和POST是HTTP协议中最常用的两种请求方法,它们的核心差异源于HTTP协议的设计哲学和底层实现。以下从协议规范、数据传输、安全性、应用场景等多个维度进行系统性分析:
# 语义差异(RFC规范)
- GET:幂等操作,用于获取资源(Safe & Idempotent)。 不应改变服务器状态(仅查询),多次请求结果相同(如刷新页面不会重复提交)。 RFC 7231: "The GET method requests transfer of a current selected representation for the target resource."
- POST:非幂等操作,用于提交资源(Non-Idempotent)。 通常改变服务器状态(如创建订单),多次请求可能产生不同结果。 RFC 7231: "The POST method requests that the target resource process the representation enclosed in the request."
# 数据传输方式
- GET参数附加在URL中
- 数据通过 URL查询字符串(Query Parameters)传递,形式如
?key1=value1&key2=value2
,长度受浏览器或服务器限制(通常2KB~8KB) - 数据 完全暴露在地址栏,可能被浏览器缓存或记录,存在安全风险
- 数据通过 URL查询字符串(Query Parameters)传递,形式如
- POST数据封装在请求体中
- 数据通过 HTTP Body 传输,支持复杂结构(如
application/x-www-form-urlencoded
、multipart/form-data
、application/json
))和大文件(如上传视频),理论上无大小限制(实际由服务器配置决定) - 数据 不直接暴露在URL中,但需配合HTTPS等加密手段确保安全性
- 数据通过 HTTP Body 传输,支持复杂结构(如
# 请求体数据结构
application/x-www-form-urlencoded
multipart/form-data
application/json
是HTTP协议中用于定义请求体
数据格式的三种不同内容类型(Content-Type)。它们各自有不同的用途和特点:
application/x-www-form-urlencoded
:- 这是HTML表单提交默认的内容类型。
- 数据以键值对的形式进行编码,类似于查询字符串的格式。例如:
key1=value1&key2=value2
。 - 适用于发送少量的ASCII字符的数据。它将表单数据转换为一个单一的长字符串,并且使用“&”来分隔键值对,“=”来连接键和值。
- 不适合传输文件或二进制数据。
multipart/form-data
:- 当需要上传文件或发送包含非ASCII字符的数据时使用。
- 数据被分为多个部分,每个部分可以包含不同的数据类型(比如文本、文件等)。
- 每个部分都有自己的头部信息,用来描述该部分内容的类型和其他元数据。
- 特别适合于上传文件或其他二进制数据,因为它不会对数据进行编码,从而避免了数据损坏的风险。
application/json
:- 主要用于发送JSON格式的数据。JSON是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。
- 它允许更复杂的数据结构,包括嵌套的对象和数组。
- 被广泛应用于Web应用程序之间的数据交换,特别是RESTful API的设计中。
- JSON格式对于传递结构化数据非常有用,尤其是在客户端与服务器端之间传输复杂的对象图时。
总结来说
选择哪种内容类型主要取决于你要发送的数据类型以及接收方如何处理这些数据。如果你正在构建一个API,通常会根据具体需求选择适当的内容类型:简单表单数据可能用application/x-www-form-urlencoded
;涉及文件上传或者复杂数据类型则倾向于multipart/form-data
;而如果是在现代Web应用或服务间交换结构化数据,则application/json
是最常见的选择。
知道它们各自的传输数据方式后,那谁效率更高,以及谁更安全呢?
# 效率的对比
先说结论:Get请求效率更高。
GET更快:POST需要发送两次TCP握手,第一次发送请求头,服务器确认后再发数据,而GET在一次TCP连接中就完成了。这会导致POST的延迟更高。另外,GET的数据会被缓存,尤其是静态资源,而POST每次都要重新发送数据,而POST默认不缓存,这也影响效率。
总结一下,GET的效率更高,原因包括:
1)更少的网络往返次数;
2)支持缓存;
3)头部数据量小;
4)协议优化如HTTP/2的支持。
而POST因为额外的预检请求、无法缓存、数据量大等原因,效率较低。但实际应用中需要根据场景选择,不能只看效率。
HTTP/2与多路复用
HTTP/2的 多路复用技术 允许同一连接上并行传输多个请求,但GET请求因数据量小、幂等性高,更适合批量并发处理
POST请求因涉及数据提交,需更严格的顺序控制和错误重试机制,降低了多路复用的优势
头部压缩 HTTP/2的HPACK算法可压缩请求头,但GET请求头部通常更简单(如无
Content-Type
等字段),压缩后体积更小
那谁更安全性呢?关于安全性的讨论,就要分数据传输和服务器状态修改两方面:
# 安全对比
# 服务器状态修改
- GET请求:
- GET请求是幂等的。这意味着无论你对同一个GET请求发送多少次,只要请求的URL和其他参数保持不变,其效果应该是相同的,并且不应该改变服务器上的状态(如数据更新、删除等)。例如,检索特定资源的信息(比如获取用户信息)应该总是返回相同的结果(假设在这期间资源没有被修改)。
- POST请求:
- POST请求不是幂等的。每次发送POST请求可能会导致服务器端状态的变化,例如创建一个新的资源或更新现有资源的数据。这意味着如果你多次提交相同的POST请求,可能会导致重复的数据插入或其他非预期的行为。例如,在线商店中的下单操作,如果重复提交了同一个POST请求,可能会导致多次购买同一商品。
从这个角度来说,get要更安全一些。
那你可能要问了,使用了get请求,那开发者仍对服务器资源进行更新,怎么办呢?
根据RFC规范,GET被设计为安全且幂等的方法。安全意味着它不应该改变服务器状态,幂等意味着多次请求的效果和一次请求相同。但用户的问题是,如果开发者错误地用GET来执行更新操作,比如删除或修改资源,这时GET是否还能保持幂等性?
答案是不能的。
幂等性是HTTP方法的语义属性,而不是实际实现的强制要求。也就是说,虽然规范规定GET应该用于获取资源,不改变服务器状态,但开发者如果错误地实现了一个GET请求来修改资源,这违反了HTTP协议的设计原则。这种情况下,多次调用该GET请求会导致服务器状态的多次改变,因此这个请求不再是幂等的。
# 常见误区
- 用GET提交数据:
若操作会改变服务器状态(如删除资源
GET /delete?id=1
),违反HTTP语义,还可能导致搜索引擎爬虫误操作。 正确做法:使用DELETE
方法或通过POST提交。 - 用POST替代GET: 若仅用于查询且参数简单,强制使用POST会增加开发复杂性,且丧失缓存优势。
# 数据传输
- GET:
- 参数通过URL Query String传递(
?key1=value1&key2=value2
) - 数据可见性高(浏览器历史、服务器日志、第三方监控工具均可捕获)
- 长度受URL最大长度限制(不同浏览器限制不同,通常2KB~8KB)
- 参数通过URL Query String传递(
- POST:
- 参数通过Request Body传递(支持多种编码格式,如
application/x-www-form-urlencoded
、multipart/form-data
、application/json
) - 数据相对隐蔽(HTTPS下可加密Body)
- 无明确长度限制(受服务器配置约束)
- 参数通过Request Body传递(支持多种编码格式,如
尽管POST在传输敏感数据时比GET更安全,因为它的数据藏在一个相对隐蔽的地方,但这并不意味着POST就是一种安全的数据传输方式。实际上,无论是GET还是POST,如果没有使用HTTPS(SSL/TLS加密),数据在网络上传输时都是明文的,容易被窃听或篡改。HTTPS通过加密HTTP请求和响应来提供一个额外的安全层,保护数据的机密性和完整性。
总结来说,在涉及敏感信息传输时,应该优先选择POST配合HTTPS的方式进行数据传输,而不是GET。但同时也要明白,真正的安全不仅仅依赖于使用POST或GET,还需要结合其他安全措施,比如使用HTTPS、实现适当的验证和授权机制等。
# Http跟Https
刚刚上文中说到的get和post都属于,http层。且提到,无论是GET还是POST,如果没有使用HTTPS(SSL/TLS加密),数据在网络上传输时都是明文的,容易被窃听或篡改。HTTPS通过加密HTTP请求和响应来提供一个额外的安全层,保护数据的机密性和完整性。
那Https和http,它们各自的定义是啥?Https又是怎么进行加密的?
# 两者区别
HTTP(超文本传输协议)和HTTPS(安全超文本传输协议)是用于网络数据传输的协议,但一个加密了。https,在 HTTP 之上增加 SSL/TLS 安全层,实现加密和身份验证。
# HTTP
- 明文传输:当使用HTTP协议时,数据以纯文本形式在网络上传输。这意味着如果一个中间人(比如在一个不安全的Wi-Fi网络中)截获了从客户端发送到服务器的数据包,他们可以直接读取这些信息,就如同服务器接收到的信息一样。没有任何加密措施保护这些数据,因此敏感信息如密码、信用卡号等极易被窃取。
# HTTPS
- 加密传输:HTTPS通过SSL/TLS协议为HTTP提供了加密层。在数据传输之前,客户端和服务器之间会进行一次SSL/TLS握手,在这个过程中双方协商出一个对称密钥,用于后续通信的加密和解密。
- 加密与解密:一旦握手过程完成,客户端发送的所有数据都会使用这个对称密钥进行加密后才在网络上传输;同样地,服务器发回给客户端的数据也会被加密。这意味着即使中间人能够截获这些数据包,由于它们是加密的,中间人无法直接读取内容。只有拥有正确密钥的客户端或服务器才能解密这些数据,看到原始信息。
加密可以分成对称加密和非对称加密,一般我们说的公钥和私钥就是非对称加密的产物。或者更严谨一些说,公钥和私钥是构成非对称加密(也称为公钥加密)体系的基础。在非对称加密中,使用一对密钥:一个公钥和一个私钥。
对称加密速度要比 非对称加密 更快。
# 证书要求
- HTTP:无需证书。
- HTTPS:需要 SSL 证书(由可信的证书颁发机构 CA 签发),用于验证服务器身份,防止伪造网站。
# 性能
- HTTP:无加密开销,速度略快。
- HTTPS:因加密/解密会消耗额外资源,但现代优化技术(如 TLS 1.3、硬件加速)已显著降低性能影响。
# 应用场景
- HTTP:适用于对安全性要求不高的场景(如静态网页、内部系统)。
- HTTPS:强制用于涉及敏感信息的场景(如登录、支付、隐私数据)。
# 加密过程
# 公钥和私钥
公钥
作用:加密
- 公开分享:正如其名,公钥是可以公开分享的,任何人都可以获取并使用它。
- 加密数据:发送方可以使用接收方的公钥来加密消息或数据。只有拥有对应私钥的人才能解密这条消息,确保了信息只能被预期的接收者读取。
- 验证签名:公钥还可以用来验证由相应私钥生成的数字签名的真实性,从而确认消息确实来自特定的发送者,并且在传输过程中未被篡改。
公钥和私钥都可以用来进行解密和加密,这是因为数学原理,这里就不展开了。
只有匹配的一对(公钥和私钥)才能正确地加密/解密或者签名/验证。
私钥
作用:解密
- 严格保密:与公钥相反,私钥必须严格保密,只有密钥的所有者才应知道和使用。
- 解密数据:接收方使用自己的私钥来解密用其公钥加密的数据,这样就可以安全地读取消息内容。
- 创建数字签名:私钥也可以用于创建数字签名。发送方可以用其私钥对消息进行签名,接收方可以使用发送方的公钥来验证这个签名,以确保消息的真实性和完整性。
通常来说,
在很多情况下,私钥确实存储在服务端。
公钥可以嵌入到客户端软件中,或者更常见的是通过网络从服务端动态获取。例如,当浏览器连接到一个HTTPS网站时,服务器会向客户端提供它的公钥(作为其SSL/TLS证书的一部分)。
特别注意,
值得注意的是,这种分配并不是绝对的。在某些应用场景下,客户端也可能拥有自己的私钥(比如在客户端认证的场景中),而服务端则保存相应的公钥以便验证客户端的身份。这种情况常见于需要双向认证(即客户端和服务端互相认证)的场合。
# CA证书
我们常说的 CA 证书,即( Certificate Authority Certificate)签发的数字证书,是互联网中用于验证身份的核心安全凭证。它的核心作用类似于“数字身份证”,由受信任的 证书颁发机构(CA) 签发,用于证明某个实体(如网站、服务器、个人)的真实性和合法性。
只有被颁发了ca证书的网站,我们去访问时,才不会提示“不安全”,之所以现在不用频繁的安装是因为,浏览器和操作系统内置的 根 CA 证书 是信任链的起点,支撑 HTTPS、电子邮件加密等场景的安全性。
以下是更进一步解释:
- CA证书的作用:当一个网站使用由受信任的证书颁发机构(CA)签发的SSL/TLS证书时,这意味着该网站已经通过了一定程度的身份验证。浏览器或操作系统内置了这些受信任CA的根证书,它们构成了信任链的基础。当你访问一个HTTPS网站时,如果该网站的证书是由这些受信任的CA之一签发的,并且证书有效且未被篡改,则浏览器会认为这个连接是安全的,不会显示“不安全”的警告。
- 内置根CA证书:现代浏览器和操作系统都预装了一系列来自不同CA的根证书。这些根证书作为信任链的起点,允许客户端(如浏览器)验证从任何给定网站接收到的SSL/TLS证书是否由一个可信赖的CA签发。这种方式减少了用户手动安装证书的需求,因为大多数常用的网站都会使用由这些已知、受信任的CA签发的证书。
- 避免“不安全”提示:只有当网站使用有效的、由受信任CA签发的SSL/TLS证书时,浏览器才会认为该网站是安全的,并允许无警告地访问。如果一个网站使用的是自签名证书(即不是由受信任的CA签发),或者证书存在问题(如过期、域名不匹配等),则浏览器通常会显示警告信息,提醒用户可能存在安全风险。