POST和GET

网络请求有OPTIONS、HEAD、GET、POST、PUT、DELETE、TRACE、CONNECT这常见的几种方式,其中最常见也就是post与get方法,在开发过程当中常常会遇到一个问题,这个接口到底是使用post请求好一点还是使用get请求好一点?两者到底有什么区别?这篇文章就将给出对应的解释。

对post与get区别的错误理解

get安全性非常低,post安全性较高

一般来说,在对新手上手的时候会跟他说这样的话,并说get是能够明文看见的,但是post不行…这个说法是有一定道理的,对于完全不知道情况的普通用户来说,安全一点确实有道理,因为从浏览器的地址上确实看不到post请求的参数,url链接也变短了,但是不代表数据被完全隐藏,实际上通过简单的开发者工具抓包就能够看到明文数据。因此某些极小的点上可以说安全,但是实际上可能并不安全。

get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。

这个说法其实是指当我们使用get请求的时候,参数会直接被显示在url当中如:https://www.duitang.com/blog/?id=1121578266。这里的参数id尚且为int,如果为中文需要url编码,以至于链接会非常的长,这个长度是有限制的,这个限制却不是get方法的限制,之所以限制是浏览器跟服务器的限制,两者为了防止链接太长导致解析压力过大影响用户体验,所以才加以限制。相对的post确实不用在意大小,因为参数传输方式不同导致解析压力并不大。

get和post的区别

get获取数据,post提交数据。

这是从语义上进行的理解,即get与post的中文翻译,其实HTTP的八种方法都能够携带参数,服务器拿到参数之后想做什么完全由服务器决定而非由请求方法决定,但是在设计之初就给出建议让get承担获取数据,让post承担提交数据的功能。

注:HTTP请求,最初设定了八种方法。这八种方法本质上没有任何区别。只是让请求,更加有语义而已。

  • OPTIONS 返回服务器所支持的请求方法
  • GET 向服务器获取指定资源
  • HEAD 与GET一致,只不过响应体不返回,只返回响应头
  • POST 向服务器提交数据,数据放在请求体里
  • PUT 与POST相似,只是具有幂等特性,一般用于更新
  • DELETE 删除服务器指定资源
  • TRACE 回显服务器端收到的请求,测试的时候会用到这个
  • CONNECT 预留,暂无使用

数据传输编码不同

Get限制Form表单的数据集的值必须为ASCII字符,因此当出现不属于ASCII编码的字符在get请求当中的时候,必须对链接进行编码,常见的如果链接当中出现空格,链接上会把空格编码成%20,不信可以粘贴以下链接到浏览器,看看链接发生的变化:

1
2
3
https://www.baidu.com/s?wd=hello world
# 以下是浏览器编码后的结果
https://www.baidu.com/s?wd=hello%20world

Post相比get支持整个ISO10646字符集,能够有更多的数据格式的兼容,因此使用起来会更加的方便,但是测试起来可能不是很方便。

其他

  • Get执行效率却比Post方法好。
  • Get是form提交的默认方法。
  • GET在浏览器回退时是无害的,而POST会再次提交请求。
  • 历史记录不能够保存post的参数,却能够保存get的请求参数。
  • POST用于修改服务器上的数据,有副作用,非幂等。

代码演示

代码采用fastpai进行演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from fastapi import FastAPI
import uvicorn
from pydantic import BaseModel

app = FastAPI()


@app.get("/")
def read_root():
return {"Hello": "World"}

class People(BaseModel): # 继承了BaseModel,定义了People的数据格式
name: str = None # 默认了name的值为None
age: int = 18 # 默认了age为18
sex: str = "renyao" # 默认了sex为renyao


@app.post("/fastapi/")
async def postdate(people: People): # 传入一个People类型的参数people
return people

if __name__ == "__main__":
uvicorn.run("test:app", host="localhost", port=5000, log_level="info")

总结

可以postget在设计上的确具有很多差异,但是实际使用的时候两者都能够满足传参的需求,但是为了标准,尽可能的使用get用于获取数据,用post提交数据。百度搜索采用的就是get获取数据,而几乎所有的账户登录都是post用于提交数据。