当前位置: 博客 /  Network  / 比较GET与POST请求

对比

/ GET POST
请求是否有主体
成功的响应是否有主体
安全
幂等
可缓存 需要设置(参见下文5.1.b)
HTML 表单是否支持

表格来源MDN

解析

下面我们逐条分析上面表格列出的特性:

1. 请求是否有主体

1.1 GET

HTTP GET 方法请求指定的资源。使用 GET 的请求应该只用于获取数据。

GET请求没有主体,提交的数据通过地址栏发送,需要传递数据时,添加数据到地址栏的问号后面,数据形式:数据名=数据值&数据名=数据值。

用法以使用axios为例,下同。

用法:.get(URL)

如果不需要传递数据,比如获取全部用户列表:.get("/userlist")

传递数据举例:

获取VIP用户:.get("/userlist?usertype=vip")

传递用户名和密码:.get("/login?user=Hanna&password=f2td")。这样发送的数据直接暴露在URL中,不要GET方法传递用户名密码这样的数据,我们可以使用POST请求处理这样的需求。

1.2 POST

HTTP POST 方法发送数据给服务器。 请求主体的类型由 Content-Type 首部指定。

POST请求有主体,提交的数据通过请求头发送,请求的数据不会加在地址后面,可以使用浏览器的控制台查看头部信息,即可看到传递的数据。

用法:.post(URL, body)

此处的body即请求的主体,比如用户登录时body可传入用户名和密码: .post(/login, { user: "Hanna" , password : "f2td" })

此处密码应该有加密处理,查看md5加密方法

2. 成功的响应是否有主体

GET请求与POST请求的成功响应都有主体。

与之相对应的是HEAD请求,HEAD请求与GET请求用法相同,但只返回HTTP报头,不返回文档主体。

3. 安全

关于安全性,很多人有误解,认为因为GET请求会在URL中暴露出传递的数据,所以是不安全的;POST请求不会直接暴露传递的数据,所以是安全的,这是错误的理解。

安全性的考量不是从这里出发。

考量一个安全的HTTP方法的关键点在于:它是否会影响服务端的状态。只读的HTTP方法是安全的。

所以GET/HEAD/OPTIONS方法是安全的,而POST/DELETE方法不是安全的。

4. 幂等

幂等这个词是英语单词Idempotent翻译而来。

我理解的幂等的意思是:一次与多次进行某操作的结果是相同的,那么这个操作即幂等的。

判断一个HTTP方法是否是幂等的:如果连续一次或多次执行具有相同效果的相同请求,仍使得服务处于相同状态,即为幂等的方法。

GET方法是幂等的:连续调用一次或者多次的效果相同(无副作用)。

POST方法不是幂等的:连续调用同一个POST可能会带来额外的影响,比如多次提交订单。

与第3点中的安全性相比较,其他的方法的安全性与幂等性相同,但DELETE方法虽然是不安全的,但却是幂等的。因为多次发送相同的删除操作结果仍然相同,不会改变服务的状态。

5. 可缓存

可缓存性有多个考量点。

  1. 对于请求本身来说分3种情况:

    a). 请求中使用的方法本身是可缓存的,如GET或HEAD方法,可以缓存响应。

    b). 如果指明了有新信息并且设置了Content-Location标头,则可以缓存对POST或PATCH请求的响应,但很少实现(浏览器支持情况不同)。

    c). 其他方法(如PUT或DELETE)不可缓存,因为其结果无法缓存。

  2. 响应的状态代码如果被应用程序缓存已知,并且被视为可缓存,那么可以缓存响应。以下状态代码是可缓存的:200,203,204,206,300,301,404,405,410,414和501。
  3. 响应中有无特定的标头,如果有Cache-Control,它会防止缓存,则不可缓存。

6. HTML 表单是否支持

HTML表单支持GET和POST请求。

举例:

6.1 GET

.get("/userlist")

<form action ="/userlist" method ="get">
  <input type ="submit" value="查看用户列表"/>
</form>

6.2 POST

.post("login", { user: "Hanna" , password : "f2td" })

<form action ="/login" method ="post">
  <label>用户名:<input type="text" name="user"/></label>
  <label>密码:<input type="password" name="password"/></label>
  <input type="submit" value="登录">
</form>

参考资料

GETPOST

- END -