您好,登录后才能下订单哦!
本篇文章为大家展示了GET和POST请求有什么区别,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
有没有简单的答案?
有的,我们万能的w3schools可以看到答案,英文点这里,中文点这里可以看到原始的网页。
GET | POST | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded或multipart/form-data。为二进制数据使用多重编码。 |
历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 |
对数据长度的限制 | 是的。当发送数据时,GET方法向URL添加数据;URL的长度是受限制的(URL的最大长度是2048个字符)。 | 无限制。 |
对数据类型的限制 | 只允许ASCII字符。 | 没有限制。也允许二进制数据。 |
安全性 | 与POST相比,GET的安全性较差,因为所发送的数据是URL的一部分。在发送密码或其他敏感信息时绝不要使用GET! | POST比GET更安全,因为参数不会被保存在浏览器历史或web服务器日志中。 |
可见性 | 数据在URL中对所有人都是可见的。 | 数据不会显示在URL中。 |
这个就是我们常说的GET和POST了。但是这并不是真正的GET和POST协议,而是我们常用浏览器(部分浏览器不一样)的封装后的样子。所以我也想聊一下关于浏览器和协议对HTTP通讯协议封装的区别。
GET和POST都是基于HTTP协议。在计算机网络7层的协议模型中,HTTP协议是隶属于最高层应用层的。也是一种基于第四层传输层TCP/IP协议的。这也导致了本质上GET和POST这两种请求其实是没有太大的区别的。区别只是请求的报文格式不一样而已。 如果我们把这两种请求用最短的方式,没有任何参数的展现成HTTP报文信息,其实就没有什么太大区别了,如下
GET /test HTTP/1.1 Host: localhost:8080
POST /test HTTP/1.1 Host: localhost:8080
GET是为了获得信息从服务器到本地,POST是为了推送信息从本地到服务器,行为上是两种截然相反的操作。
由于GET方法的目的就是为了获取信息,当我们假设如果数据库的数据不变,请求的参数不变(基于当前时间的参数,应当认为请求参数是变化的,比如last_5_minutes),那么我们返回的结果也应该是不变的。反复的读取数据库中的数据,不应该对数据本身产生副作用(统计信息除外)。所以我们说GET是符合幂等性(idempotent)。因此可以被浏览器与其他客户端缓存。
POST方法的目的是创建资源,即使我们请求的参数不变,但是对数据库而言都是要创建一个新的记录,虽然所有的数值都和前面的一样,但是这也是可以合理存在的,只是在数据库中主键不同罢了。这样的创建流程对数据库的数据有实质影响,每创建一次就多一条数据。因此我们说POST是不符合幂等性的。因此也不可以被缓存。试想一下,如果POST请求可以被缓存,我们想在电商网站买东西,前后下单2次,都是一样的东西。POST返回的信息是直接扫描本地缓存,直接返回第一次的下的成功,并没有进行第二次的下单提交。或者如果可以用书签保存链接,是不是点一次书签查看就下了一次订单?此外在发出POST请求后,有些页面刷新的时候回弹出窗口 “确认重新提交表单”。这些都是POST不能被缓存的原因了。
但是如果说到实际使用,也不是不可以交换功能。毕竟都是使用相同的协议。所以我可以设计一个API,用GET方法的请求来插入数据,用POST方法的请求来返回查询数据。也许用POST方法请求数据还能理解,但是坚决不推荐用GET方法来插入数据,这样做只会徒增维护难度。
特点 | 浏览器GET | 浏览器POST | RESTful接口GET | RESTful接口POST |
---|---|---|---|---|
使用场景 | 特指在浏览器中不使用Ajax的HTTP请求,也就是原生的那些请求,可以追溯到HTML诞生的时候。 | 特指在浏览器中Ajax API,Java中的httpClient,postman工具等发出的请求。 | ||
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交) | 无害 | 数据会被重新提交 |
书签 | 可收藏为书签 | 不可收藏为书签 | 没有此功能 | 没有此功能 |
缓存 | 能被缓存 | 不能缓存 | 能被缓存 | 能被缓存,但非常不推荐 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded或multipart/form-data。为二进制数据使用多重编码。 | 多重编码类型均可 | 多重编码类型均可 |
历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 | -- | -- |
对数据长度的限制 | 是的。当发送数据时,GET方法向URL添加数据;URL的长度是受限制的(URL的最大长度是2048个字符) | 无限制 | 无限制 | 无限制 |
对数据类型的限制 | 只允许ASCII字符。 | 没有限制。也允许二进制数据。 | 无限制 | 无限制 |
安全性 | 与POST相比,GET的安全性较差,因为所发送的数据是URL的一部分。在发送密码或其他敏感信息时绝不要使用GET! | POST比GET更安全,因为参数不会被保存在浏览器历史或web服务器日志中。 | 不安全 | 不安全 |
可见性 | 数据在URL中对所有人都是可见的。 | 数据不会显示在URL中。 | -- | -- |
我们先来看看在1999年6月的RFC2616-4.3HTTP协议1.1中第33页提及到内容如下:
A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
然而RFC2616-4.3已经过时了,推出了新的修正RFC7230-3.3。但是问题是最新的规范居然是更加宽松?我对此表示很无奈。
我们再来看看在2014年6月的RFC7230-3.3HTTP协议1.1消息语法和转发中第28页提及到内容如下:
The presence of a message body in a request is signaled by a Content-Length or Transfer-Encoding header field. Request message framing is independent of method semantics, even if the method does not define any use for a message body.
所以从现在最新的协议来看,携带body信息已经无所谓使用的是什么方法了。但是我真的建议在GET请求中不要带body。
首先我们要明确的是我们经常说的GET请求长度限制是之URI请求长度限制。
我们先来看看在1999年6月的RFC2616-3.2.1
The HTTP protocol does not place any a priori limit on the length of a URI. Servers MUST be able to handle the URI of any resource they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET-based forms that could generate such URIs.
我们再来看看2014年6月的RFC7230-2.5HTTP协议1.1消息语法和转发中第13页提及到内容如下:
HTTP does not have specific length limitations for many of its protocol elements because the lengths that might be appropriate will vary widely, depending on the deployment context and purpose of the implementation.
我们同样来看看2014年6月的RFC7230-3.1.1HTTP协议1.1消息语法和转发中第21页提及到内容如下:
HTTP does not place a predefined limit on the length of a request-line, as described in Section 2.5. A server that receives a method longer than any that it implements SHOULD respond with a 501(Not Implemented) status code. A server that receives a request-target longer than any URI it wishes to parse MUST respond with a 414 (URI Too Long) status code (see Section 6.5.12 of [RFC7231]).
这就是HTTP协议规范里的要求,从来没有要求过URI的长度限制,但是为什么我们会有URL长度限制的问题呢? 我们再来看看微软谷歌等大厂的规范
微软 IE浏览器的规范
Microsoft Internet Explorer has a maximum uniform resource locator (URL) length of 2,083 characters. Internet Explorer also has a maximum path length of 2,048 characters. This limit applies to both POST request and GET request URLs.
Google Chrome浏览器的规范
In general, the web platform does not have limits on the length of URLs (although 2^31 is a common limit). Chrome limits URLs to a maximum length of 2MB for practical reasons and to avoid causing denial-of-service problems in inter-process communication.
所以现在我们现在知道URI长度限制只是各个浏览器厂商自己的限制,且限制还不统一。而HTTP规范根本就没有规定最长长度限制,也就是说看你的服务器自己决定吧。
网上很多人都说POST方法比GET方法更安全,主要是POST数据部分不直接暴露在URL上,而GET的参数全都在URL上,更容易看到。但是,从传输数据上来看,他们都是明文传输,每次请求和返回的字节都会以明文的形式在网上传输。如果想要安全传输,通用的做法是使用SSL协议来加密,也就是业界的标准规范HTTPS。当然HTTP协议和SSL协议是两个独立的协议。如果你有幸参与一些特殊项目,那么HTTP可能就不是用SSL协议加密了,也许会换成国密SM协议,参见国密标准网密码标准应用指南。
所以在网上传输数据如果想要更安全,一定要用HTTPS协议。但在网页设计上,决定不能把密码密钥一类的东西用URL传输,毕竟还是有可能使用者被身后的人偷窥到URL上的信息。
网上很多人说GET方式的请求,浏览器会把请求HEADER和参数一并发送出去,服务端响应200,请求成功。而POST方式的请求,浏览器会先发送HEADER给服务器,服务器响应代码100 continue,浏览器再发送一个DATA给服务器,服务器响应200,请求成功。
然而这也只是说浏览器会这样做,并不是HTTP协议中的规范。这一点和我们刚才提到的URI的长度一样,都是由各个浏览器厂商所制定的规则。我们假设一下,如果GET方法的URL太长一个TCP包放不下怎么办,那是不是GET也要发2个TCP包?而且FireFox浏览器针对POST的小数据发送也是一个TCP包,这又怎么解释?所以最合理的方法就是依据浏览器和客户端的自身规则而定。
如果数据量很小,1次TCP包和2次TCP包没有太大的时间差。如果数据量很大,通常POST请求不是一次TCP包能包含所有的。应该会有很多的TCP包。如果先发一个HEAD过去,如果服务器没有回应,那么数据包的部分就可以不发送了。但服务器都响应失败了,你还在乎是否发送1次还是2次?
回到文章标题,再换一种说法,如果有人问你GET和POST的区别,我们来回答发送1次还是2次TCP包的问题,你觉得你用传输层协议(TCP)的答案能回答应用层协议(HTTP)的问题?
上述内容就是GET和POST请求有什么区别,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。