从 HTTP 协议的角度来说,它们除了语义不同,没有本质区别。
但受浏览器默认行为的影响,才在实际开发中有了一些区别。
只是约定(并不属于HTTP规范):get 请求参数在 url 中,post 请求参数在请求体中。
虽然完全可以在 get 请求的请求体中添加参数,post 请求的 url 中添加参数。
但实际开发中,一般不会在 get 请求的请求体中添加参数(MDN参考),而可能在 post 请求的 url 中添加参数。
因为参数位置的原因,get 请求参数的大小有限,同时也会暴露数据,如果有敏感数据不应该使用 get 请求,至少不应该放到 url 中。而 post 请求参数大小没有限制。
POST 方法简约报文举例:
POST /test HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
field1=value1&field2=value2
GET 方法简约报文举例:
GET /test?field1=value1&field2=value2 HTTP/1.1
Host: localhost
get 请求只能传递 ASCII 字符,非 ASCII 字符需要编码;post 请求没有限制。
本质是:url 中只能传递 ASCII 字符。
ASCII码一共有 128 字符
// 控制台打印试试
for (let i = 0; i < 128; i++) {
console.log(String.fromCharCode(i));
}
如果当前页面是通过 post 请求得到的,则浏览器会提示用户是否重新提交。get 请求无提示。
举例:
// 服务端
var Koa = require("koa");
var Router = require("koa-router");
var app = new Koa();
var router = new Router();
router.get("/", (ctx, next) => {
ctx.body = "hello";
});
app.use(router.routes());
app.listen(3000);
<!-- 前端 -->
<form action="http://localhost:3000" method="post" target="_blank">
<input type="text" />
<button>提交</button>
</form>
get 请求的地址可以被保存为浏览器书签,post 不可以。
实际表现,虽然二者都可以保存为书签。但访问 post 保存的书签时,会自动变为 get 请求!
(gif 有点大,稍微等待看下效果)
get 请求的响应,浏览器会主动缓存。
post 请求的响应,浏览器不会主动缓存,需手动设置(参考 浏览器缓存机制)。
原因:
get 请求一般用于向服务器获取资源,所以默认会缓存。
post 请求一般用于和服务器进行交互,可能会修改服务器的数据,所以默认不会缓存。
虽然 RESTful API 设计指南 中,
但实际开发中,post 把这些都干了也没有什么问题,主要看公司有没有要求和规范。
post 用于获取数据,有可能是因为请求数据量比较大,或是数据结构比较难处理。
以上。