一、HTTP 请求方法
HTTP 协议定义的方法类型大概有以下 11 种:
| 方法 | 说明 | 支持的 HTTP 协议版本 |
|---|---|---|
| GET | 获取资源 | 1.0、 1.1 |
| POST | 传输实体主体 | 1.0、 1.1 |
| PUT | 传输文件 | 1.0、 1.1 |
| DELETE | 删除文件 | 1.0、 1.1 |
| HEAD | 获得报文首部 | 1.0、 1.1 |
| OPTIONS | 询问支持的方法 | 1.1 |
| TRACE | 追踪路径 | 1.1 |
| PATCH | 对 PUT 的补充,用来对已知资源进行局部更新 | 1.1 |
| CONNECT | 要求用隧道协议连接代理 | 1.1 |
| LINK | 建立和资源之间的联系 | 1.0 |
| UNLINE | 断开连接关系 | 1.0 |
注:目前大部分的网站使用的都是 HTTP 1.1 的协议。
二、相爱相杀的 GET 和 POST
1.相同点
GET 和 POST 是 HTTP 请求中最常用的两种请求方法,它们的底层都是基于 TCP/IP 实现的。
2.不同点
2.1 本质上(约定和规范)
- 定义 GET 请求是用来获取资源的,也就是进行查询操作的,而 POST 请求是用来传输实体对象的,因此会使用 POST 来进行添加、修改和删除等操作。
- GET 和 POST 的参数传递也是不同的,GET 请求是将参数拼接到 URL 上进行参数传递的,而 POST 是将请参数写入到请求正文中传递的。
2.2 安全性
POST 比 GET 更安全,因为参数不会被缓存、不会作为 URL 的一部分、不会被保存在浏览器历史记录或 web 服务器日志中。所以,在发送密码或其他敏感信息时绝不要使用 GET。
经测试,chrome和firefox下如果检测到get请求的是静态资源,则会缓存,如果是数据,则不会缓存,但是IE什么都会缓存起来。
2.3 参数长度限制不同
- GET 请求的参数是通过 URL 传递的,http协议并未规定 Get 的 URL 长度限制,但是浏览器和web服务器限制了URL的长度,通常为 2048 个字符(Chrome 最大长度限制为8182byte);
- POST 请求参数是存放在请求正文(request body)中的,没有大小限制。
2.4 幂等性
幂等性:HTTP/1.1 中的定义是指一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外)。
需要注意的是,幂等还包括第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资源产生副作用。
HTTP 协议明确规定,put、get与delete请求都是具有幂等性的,而post为非幂等性请求。
多次发出相同的 GET 请求应该会产生相同的响应;而 POST 请求则不是。因此:
- GET 请求可以直接进行回退和刷新,不会对用户和程序产生任何影响;
- POST 请求如果直接回滚和刷新将会把数据再次提交(浏览器应该告知用户数据会被重新提交);
- GET 请求的地址可被收藏为书签;
- POST 请求的地址不能被收藏为书签,尝试为POST添加书签只会导致对URL进行GET操作。
2.5 对数据类型的限制
- GET 只允许 ASCII 字符;
- POST 没有限制,也允许二进制数据。
一般来说:无论是URL还是请求参数中的非ASCII码都会字符被URL编码成ASCII码字符吗?
如果你的 Get 请求中有非 ASCII 字符,会在请求之前进行转码,得到没有非 ASCII 字符的 URL,然后去发起 Get 请求,这样请求的路径里不是没有非 ASCII 字符么?
2.6 传输速度
结论:post比get慢。原因如下:
- post请求包含更多的请求头,post需要在请求的body部分包含数据,所以会多了几个数据描述部分的首部字段;
- 最重要的一条,post在真正接收数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据,即 GET 产生一个 TCP 数据包,而 POST 产生两个 TCP 数据包;
post请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送post请求头(第三次握手)
(4)服务器返回100 Continue响应
(5)浏览器发送数据
(6)服务器返回200 OK响应
get请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送get请求头和数据(第三次握手)
(4)服务器返回200 OK响应
-
get会将数据缓存起来,而post不会;
-
post不能进行管道化传输。
管道通信:把需要发送到服务器上的所有请求放到输出队列中,在第一个请求发送出去后,不等到收到服务器的应答,第二个请求紧接着就发送出去。
管道通信有安全隐患,这对于 Post 这样的非幂等请求是行不通的(比如支付的时候,多发送几次就惨了)。默认情况下大部分浏览器(除了opera)是不进行管道化传输的,除非手动开启。
三、Put 和 Delete
1.PUT
PUT 用于将数据发送到服务器来创建/更新资源。
该请求类似数据库的 update 操作,用来修改数据内容。
但是 PUT 请求是幂等的(idempotent),也就是说无论进行多少次 PUT 操作,其结果并没有什么不同,这也是它与 Post 的不同点。
2.Delete
Delete 是用来删除某一个资源的,该请求类似数据库的 delete 操作。
参考 & 鸣谢
面试突击71:GET 和 POST 有什么区别? - 掘金 (juejin.cn)
什么时候用get?什么时候用post? - 简书 (jianshu.com)
上德不德,是以有德。下德不失德,是以无德。上德无为,而无以为也。上仁为之,而无以为也。上义为之,而有以为也。上礼为之,而莫之应也,则攘臂而扔之。故失道而后德,失德而后仁,失仁而后义,失义而后礼。夫礼者,忠信之薄也,而乱之首也。前识者,道之华也,而愚之首也。是以大丈夫居其厚,而不居其薄,居其实,而不居其华。故去彼取此。