GET请求和POST请求的区别
经常遇到「既然GET请求可以做POST请求的事情,为什么还要区分GET和POST而不只使用一个请求?」的问题。作为在实际中被使用最广的两个请求方法,这个问题其实挺难回答的,但万物总有其根由,今天就追根究底。
查看RFC规范再加上之前查过的一些二手文章,整理了如下的观点:
GET被强制服务器支持
GET 通常用于请求服务器发送某个资源。在HTTP/1.1中,要求服务器实现此方法;POST请求方法起初是用来向服务器输入数据的。在HTTP/1.1中,POST方法是可选被实现的,没有明确规定要求服务器实现。
浏览器对URL的长度有,所以GET请求不能代替POST请求发送大量数据
RFC 2616 (Hypertext Transfer Protocol — HTTP/1.1) states in section 3.2.1 that there is no limit to the length of an URI (URI is the official term for what most people call a URL)
RFC 2616 中明确对 uri 的长度并没有。不过虽然在RFC中并没有对uri的长度进行,但是各大浏览器厂家在实现的时候了URL的长度,可查到的是IE对长度为;而chrome遇到长度很长的URL时,会直接。
所以这条结论算是正确的。
GET请求发送数据更小
只能通过写代码验证了:下面第一个文件是服务器代码,作用是在客户端发送GET和POST请求的时候返回200状态码。第二个文件是客户端HTML文件,点击两个button,分别发送GET请求和POST请求。
import koa from 'koa'
import fs from 'mz/fs'
const app = koa()
app.use(function* (next) {
if(this.path == '/test')
return this.status = 200
yield next
})
app.use(function* (next) {
this.type = 'html'
this.body = yield fs.readFile('./index.html')
yield next
})
app.listen(8080)
console.log('koa server port: 8080')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="get">GET</button>
<button id="post">POST</button>
</body>
<script>
function http(type) {
return function (url) {
var req = new XMLHttpRequest()
req.open(type, url)
req.send()
}
}
var getDom = document.getElementById('get')
, postDom = document.getElementById('post')
, get = http('GET')
, post = http('POST')
getDom.addEventListener('click', function () {
get('/test')
})
postDom.addEventListener('click', function () {
post('/test')
})
</script>
</html>
从上两张图可以看到POST请求的headers要比GET请求多了两个属性。所以这条结论其实也算是对的,不过从请求发送时间来看的话,其实两者并没有差别。
GET请求是安全的
Of the request methods defined by this specification, the GET, HEAD,OPTIONS, and TRACE methods are defined to be safe.
这里的安全指的是在规范的定义下,Get操作不会修改服务器的数据
GET请求是幂等的
A request method is considered "idempotent" if the intended effect on
the server of multiple identical requests with that method is the
same as the effect for a single such request. Of the request methods
defined by this specification, PUT, DELETE, and safe request methods
are idempotent.
从上面可以看到GET请求是安全的,在幂等性中说PUT和DELETE以及安全method都是幂等的,所以GET自然也被包括了。
POST请求不能被缓存
我们在实际使用过程中对HTTP请求的优化大多数都放在GET请求上,比如对没有数据变化的请求(网站中常用的静态文件)做缓存,在潜意识中认为只有GET请求才可以被缓存,所以从来也不会考虑POST请求的缓存优化,然而在RFC中提到GET和POST以及HEAD都是可以被缓存的。不过不要惊讶,之前不知道POST可以被缓存是因为标准也很无奈,浏览器的实现总是比标准厉害。
In general, safe methods thatdo not depend on a current or authoritative response are defined as cacheable; this specification defines GET, HEAD, and POST as cacheable, although the overwhelming majority of cache implementations only support GET and HEAD.