大家在初学 HTTP 协议的时候,可能从来没有想到面试的时候每次都会被问到 GET 和 POST 请求的区别吧。今天我们就来寻找一下标准答案。
简单回忆一下 HTTP
MDN 上对 HTTP 的描述是这样的:
超文本传输协议是用于传输诸如HTML的超媒体文档的应用层协议。它被设计用于 Web 浏览器和 Web 服务器之间的通信,但它也可以用于其他目的。`
其中 HTTP 定义了一组请求方法,以表明要对给定资源执行的操作。这些方法是一组有语义的动词或名字,主要有 GET/HEAD/POST/PUT/DELETE/CONECT/OPTIONS/TRACE/PATCH
,我们最常用的是 GET 和 POST,MDN 上对 GET 和 POST 用途的描述分别为:
- GET方法请求一个指定资源的表示形式. 使用GET的请求应该只被用于获取数据.
- POST方法用于将实体提交到指定的资源,通常导致状态或服务器上的副作用的更改.
有了这些基础就对后面的比较有帮助了。
标准回答
HTTP 方法:GET 对比 POST - w3school 给出来的分析算是比较浅显和直观的了,总结一下就是:
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被加入到书签,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
- 大多数浏览器通常都会限制url长度在2K个字节,而大多数服务器最多处理64K大小的url。
其中比较重要的是1、10。再回答第一条的时候,可以多回答一句,GET 请求是幂等的,而 POST 不是。
RFC7231里定义了HTTP方法的几个性质:
- Safe - 安全
安全主要是说一个方法在语义上需要是只读的,就是不能修改服务器状态(或者说是数据),比如网络爬虫在爬到这个 URL 的时候,或者用户在浏览器书签和地址栏记忆里访问 URL 的时候,不至于对服务器造成服务器状态的的改变。RFC定义,GET, HEAD, OPTIONS 和 TRACE 这几个方法是安全的。
- Idempotent - 幂等
幂等的概念是指同一个请求方法执行多次和仅执行一次的效果完全相同。这样比如浏览器在返回或者刷新到有 POST 请求的时候,会给用户一个提示信息,防止非幂等的 POST 请求会给修改服务端状态,而不是用户想要的效果。安全的方法都是幂等的。RFC 规定 PUT、DELETE 和上面提到的GET、 HEAD、OPTIONS、TRACE 方法都是幂等的。
- Cacheable - 可缓存性
一个方法可以被缓存,就是在某些情况下可以被缓存,比如我们请求页面时候,一些静态文件是可以直接从缓存中获取的,比如 css、js、图片等文件。RFC 里规定 GET,HEAD 和某些情况下的 POST 都是可缓存的。
其实 GET 和 POST 更多的区别是在语义上的区别,在语法上的区别并不是重点。因为服务端拿到 GET 数据以后,也可以去修改服务器状态。
关于 POST 会发2次请求的争论
知乎专栏有过 GET 请求和 POST 请求一个本质区别的讨论,就是 GET 请求只会发一个请求,而 POST 请求会发两次 HTTP 报文。最后证明并不算是2者的差别,想吃瓜的群众可以看下面参考文档中的4和5.