谈"httpget和post的区别"

author author     2022-08-18     586

关键词:

——以下内容如有各种问题,烦请指出,谢谢各位^_^——

 

最基本的Java程序员面试题都有这个题

——http get和post的区别?

不少人大学还没毕业就知道,就算不知道也会去搜,我记得我快毕业那会,简单搜出来,排在前面的大概就这么几个区别:

1、get用于获取数据,post用于提交数据

2、get提交参数追加在url后面,post参数可以通过http body提交

3、get的url会有长度上的限制,则post的数据则可以非常大

4、get提交信息明文显示在url上,不够安全,post提交的信息不会在url上显示

5、get提交可以被浏览器缓存,post不会被浏览器缓存

现在回头总结下,发现自己快毕业哪会自己真是什么都不知道啊,当时网上搜出来的这份东西就是有误的啊,国内也是各种传来传去,错误的到处看得到,都快成标准答案了。今年5月用netty http 些服务端程序时,调接口无意发现了原来get也可以使用http body提交数据,抽空弄了下tomcat,发现也可以啊。今天整理笔记看到了这里,觉得有必要在博客上记录一下,避免后来人继续犯错。

一点一点的说 第1点:rfc2616说get方法用于获取指定uri所代表的资源,应该设计成幂等的(其他情况不变时,多次请求返回同样的结果,差不多算是只读),不过在很长一段时间内,get方法都有“写”功能,最简单的例子就是/delete?id=1,然后很常见的就是jsonp形式的请求。 post方法该做什么rfc2616说是叫服务器自己决定,现实中用post进行只读操作的很多啊,一些提供http接口的数据库都有post json进行只读查询的功能,post提交表单数据进行写操作到处都是。 所以第一点这个,不怎么好评价,现在的多数用途下第一点就是废话,什么意思都没表达。不过现在RESTful炒得火热,在RESTful的理念下,第一点差不多算是对的,不过RESTful任重道远啊,比起现在只用get/post的http,毕竟实质性的功能没有多大变化。 应该是今后很长一段时间内,get和post在第一点上基本没区别,能用post实现的操作,基本上也能用get实现。

第2点:这一点是最坑的。 http没明确规定什么get/post方法要用什么样的方式传输数据,之所以出现第2点所说的情况,原因主要有两点:浏览器设计、服务器设计,浏览器不支持get+httpbody是比较常见的,fiddler模拟请求时,如果是get,你填下面的body部分会红色显示,告诉你这样不好,仅仅是不好,因为fiddler并没有禁止get+body这种请求,但看得出它不建议你用这种方式的请求。

技术分享

常见的servlet服务器,比如tomcat,默认不解析get的body部分,造成了get不能用body传递参数的现象。我写了个简单的例子,对比看下就知道是tomcat没解析get的body,不是get本身不能使用body传参。

 1 import java.io.IOException;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 
 5 import org.apache.commons.lang3.StringUtils;
 6 import org.springframework.stereotype.Controller;
 7 import org.springframework.web.bind.annotation.RequestMapping;
 8 import org.springframework.web.bind.annotation.ResponseBody;
 9 
10 @Controller
11 public class TestController {
12     private static final String NEW_LINE = StringUtils.CR + StringUtils.LF;
13 
14     @ResponseBody
15     @RequestMapping("/testLogin")
16     public String testLogin(HttpServletRequest req, String username, String pwd) throws IOException {
17         StringBuilder builder = new StringBuilder();
18         builder.append("req.method: ").append(req.getMethod()).append(NEW_LINE);
19         builder.append("req.queryString: ").append(req.getQueryString()).append(NEW_LINE);
20         int contentLength = req.getContentLength();
21         String body = null;
22         if (contentLength > 0) {
23             byte[] bytes = new byte[contentLength];
24             req.getInputStream().read(bytes);
25             body = new String(bytes, "UTF-8");
26         }
27         builder.append("req.body: ").append(body).append(NEW_LINE);
28         builder.append("req.params.username: ").append(req.getParameter("username")).append(NEW_LINE);
29         builder.append("req.params.pwd: ").append(req.getParameter("pwd")).append(NEW_LINE);
30         builder.append("username: ").append(username).append(NEW_LINE);
31         builder.append("pwd: ").append(pwd);
32         System.err.println(builder);
33         return builder.toString();
34     }
35 }

上面这个controller功能很简单,就是打印请求参数,并且原样返回,结果如下

技术分享

上面张图看出来,body部分可以获取得到,但是tomcat没有读取了ServletInputStream中的body并解析body,造成req.getParam获取不到对应的参数。

 

技术分享

这张图就是把方法换成POST,Request的其余一个字符都没有变,可以看到tomcat读取了ServletInputStream中的body,并进行解析,造成了手动读取ServletInputStream时流中没有内容了,打印出来的req.body显示无内容,req.getParam能够获取到解析完成后对应的参数。

 

技术分享

这张图是普通的get+queryString,效果和post+body一样。

 

对比上面三个结果就知道,get不是不能使用body传参,只是浏览器和服务器进行了限制。浏览器的限制我不知道,这个研究得不多,tomcat的限制倒是可以根据配置解除。

官方配置:http://tomcat.apache.org/tomcat-8.0-doc/config/http.html

具体就是这一项

技术分享

默认是POST,也就是当Content-Type=application/x-www-form-urlencoded(提交Web表单时的标准数据传输格式,跟url传参格式一样,使用键值对,用&区分)时,只对post方法的body部分进行解析。把tomcat的server.xml中Http1.1的Connector配置上这项,就能够让tomcat能够解析get的body部分,也就能够在tomcat上使用get+body的方式了。

技术分享

技术分享

上面这图是修改配置后的结果,改完配置后get+body跟post+body功能一样了。

第3点:这个跟第2点一样,rfc2616中说了不对uri长度做限制,要求http能够实现无限长度的uri,无限长度的body。

原话是下面这个:

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. A server SHOULD return 414 (Request-URI Too Long) status if a URI is longer than the server can handle (see section 10.4.15).

Note: Servers ought to be cautious about depending on URI lengths above 255 bytes, because some older client or proxy implementations might not properly support these lengths.

rfc2616:http://www.ietf.org/rfc/rfc2616.txt

现实中就是太长的url没什么用,太长的body部分也不是很好,所以各种客户端服务端的实现默认都有限制的这http种各个部分的长度。浏览器的我不清楚,服务端的http实现一般这个长度都是可以配置的,netty http的HttpServerCodec默认是4K长度(整个请求行,uri是请求行里面大头),tomcat是用maxHttpHeaderSize来配置请求行和header部分的总长度;post长度,netty http默认是8K,tomcat默认是maxPostSize=2M,tomcat的配置设置成-1就是无限长度,但是这么做在实际中一点意义没有。

第4点:安全,这个扯得有点远,也随便扯扯。 不是别人一眼看不到的就是安全,不是别人一眼看得到就不安全。http抓包很容易的,对路由器做点手脚就能够抓一堆移动设备的http请求包,移动设备的http请求你自己都一眼看不到,更不用说别人了,想要安全,还是用https吧,大多数人看到了也没用。

另外扯一句,Base64不是加密,用这个加密就是掩耳盗铃啊。

 

第5点:关于http response的缓存

get被建议做成幂等的,缓存是很有必要的,一般静态资源的get请求都是会设置有效缓存时间的,这一点很容易想明白。很多时候缓存get在服务器和浏览器中是默认行为,这对大量使用get请求的ajax不利,所以ajax请求一般会在请求url后加上一个随机数,浏览器和服务器就认为它是不同的get请求,不会缓存这个get请求。

关于post的缓存,现在的实际情况是绝大多数浏览器都不支持post缓存,但是rfc2616中关于post的response是否缓存说得很混乱,主要有两个地方说了post的缓存。

第一个是关于post方法的说明中(9.5小节):

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.

这段话也就是说,是否缓存post的response,是根据http请求头中的Cache-Control、Expires决定的。

还有一个位置,13.10小节(13节是专门说缓存的):

In this section, the phrase "invalidate an entity" means that the cache will either remove all instances of that entity from its storage, or will mark these as "invalid" and in need of a mandatory revalidation before they can be returned in response to a subsequent request.

Some HTTP methods MUST cause a cache to invalidate an entity. This is either the entity referred to by the Request-URI, or by the Location or Content-Location headers (if present).

These methods are:

- PUT

- DELETE

- POST

这段话是说 PUT DELETE POST 应该让缓存无效uri代表的实体——删除该实体的所有实例存储,或将这些标记为“无效”并需要强制性重新验证,然后才能返回以响应后续操作请求。

我觉得这两处规定有冲突啊,都说叫POST无效缓存,那还缓存毛线啊!

stackoverflow上有个问题讨论这个,感觉也没说明白:http://stackoverflow.com/questions/626057/is-it-possible-to-cache-post-methods-in-http

所以呢,这个post的缓存有待继续确认下,或者哪位大牛点明下,我个人暂时还是不太明白rfc2616真正想说的是什么。

总结:工作也有些时间了,我也不是一个纯小白了,了解了一些方法和途径,该多靠自己的力量去弄懂些东西。还有,这个问题一路走来也是深有感触啊,网上搜到的东西不一定正确,排名靠前的也不一定是最真的,但确是那些初学者最能依赖的。像我这种工作的时候自己捣鼓无意间发现的还算幸运啊,毕竟这个问题,对于很多人,毕业的时候就定型了,可能会一辈子错下去。

 

——以上内容如有各种问题,烦请指出,谢谢各位^_^——

Android 的 SOAP 1.1、SOAP 1.2、HTTP GET 和 HTTP POST 方法有啥区别?

】Android的SOAP1.1、SOAP1.2、HTTPGET和HTTPPOST方法有啥区别?【英文标题】:WhatisthedifferencebetweenSOAP1.1,SOAP1.2,HTTPGET&HTTPPOSTmethodsforAndroid?Android的SOAP1.1、SOAP1.2、HTTPGET和HTTPPOST方法有什么区别?【发布时间】:2012-01-2504:13:04【问题描述... 查看详情

没有属性名的 Http get 和 post 方法

】没有属性名的Httpget和post方法【英文标题】:Httpgetandpostmethodwithoutattributename【发布时间】:2019-04-0812:55:02【问题描述】:我正在使用.netCore2.1WebAPI。我添加了每个方法[HttpGet("....")]或[HttpPost("....")],如下所示。但... 查看详情

[httppost]和[acceptverbs(httpverbs.post)]区别

...可以回应GET请求那么我们应该怎么做呢?首先[HttpPost]和[HttpGet]是不能同时存在一个action上但是[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)] 查看详情

ajax请求的时候get和post方式的区别

首先看一下get、post的区别1、get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTPpost机制,将表单内各个字段与其内容放置在HTMLHEADER内一起传送到ACTION属性所... 查看详情

解析ajax请求post和get的区别

参考技术A解析ajax请求post和get的区别  对于ajax请求post和get的区别来说,最简单的是  1.使用Get请求时,参数在URL中显示,而使用Post方式,则不会显示出来  2.使用Get请求发送数据量小,Post请求发送数据量大  3.get请求需注意... 查看详情

http POST和http GET之间的澄清[关闭]

】httpPOST和httpGET之间的澄清[关闭]【英文标题】:ClarificationbetweenhttpPOSTandhttpGET[closed]【发布时间】:2013-01-1114:01:51【问题描述】:我已经阅读了大量关于http帖子和httpget方法之间区别的文章。我只是对这两者中哪一个在安全性方... 查看详情

http请求中get和post请求的区别?(代码片段)

...uot;get"。Post的请求方式1.设置表单的method="post"区别Get请求1.请求参数及值会添加到请求路径后面,但是参数数据量有大小限制。2.请求参数会显示在浏览器的地址栏,可能会造成信息泄露,不安全。Post请求1.将请求参... 查看详情

jsp调用servlet时get方法和post方法有啥区别?

...uest,response);去调用get方法,这样和直接调用get方法有什么区别吗,请知道的朋友帮忙解答一下这个method="get"是系统默认的呀...所以你写不写结果都是一样的...但是如果你要是写成method="post"结果就不一样了....method=&... 查看详情

form表单中method="post/get'的区别

...输过程中分别对应了HTTP协议中的GET和POST方法。二者主要区别如下:1、Get是用来从服务器上获得数据,而Post是用来向服务器上传递数据。2、Get将表单中数据的按照variable=value的形式,添加到action所指向的URL后面,并且两者使用... 查看详情

post,参数放在ulr和放在body的区别

...参数可以放在url上也可以放在body上,请问这两者有什么区别吗?有哪些接口参数只能放在url?有哪些接口参数只能放body?参考技术A那么有什么不同呢?先看一个例子:一个二级级联动态下拉列表框,一级分类(即大类别)id=&qu... 查看详情

用javascript解析httpget查询字符串

/*ParseGETparameters(basedonhttp://www.netlobo.com/url_query_string_javascript.html)*/functionparseHttpGet(key){key=key.replace(/[[]/,"[").replace(/[]]/,"]&qu 查看详情

get请求和post请求的特点和区别

参考技术A1.GET是"得",即从服务器获取数据;2.GET请求可以被缓存;3.GET请求的效率更高,但是安全性相对于POST来说要更差,因为URL会包装用户名,密码等敏感信息;4.在HTTP协议中,虽然没有对GET请求限制数据大小。但是... 查看详情

关于httpget和form表单post提交数据大小限制

...是如题的两个,回来后特意去查找了一下,关于httpget提交数据上限,之前只知道数据上限差不多是几kb大小,具体为什么却没有了解httpget是通过url来传递数据,url不存在上限的问题,http协议也没有对utl长... 查看详情

dopost()和doget()方法的区别?

...示出来,而POST提交,地址栏不会改变2、传输数据的大小httpGet请求由于浏览器对地址长度的限制而导致传输的数据有限制。而POST请求不会因为地址长度限制而导致传输数据限制。3、安全性,POST的安全性要比GET的安全性高。由于... 查看详情

关于http协议的get方法和post方法的区别和用法

GET是返回URL所指的文档,一般情况下用于请求下载Web页面。例如,GEThttp://XXXXXPOST与GET方法相反,请求服务器接受制定的文档,但是它不是替换已有的文档,只是将新数据附加到它的后面。一般可用来向新闻组发送一条消息,或... 查看详情

substr和substring的区别

...没有第2个参数,都是直到字符串末尾。②substring和slice的区别则是,slice可以接受“负数”,表示从字符串尾部开始计数;而substring则把负数或其它无效的数,当作0。"helloworld!".slice(-6,-1)//"world""helloworld!".su... 查看详情

jquery$.ajax$.get$.post的区别是啥噢?

get和Post好理解涩、但是$.ajax是什么意思哦?他们3有啥区别呢?$.ajax是jQuery底层AJAX实现,$.ajax是一种通用的底层封装,$.ajax()请求数据之后,则需要使用回调函数,有beforeSend、error、dataFilter、success、complete等。$.get$.post是简单易用... 查看详情

浅谈并发和并行的区别

   我们就拿电脑的cpu举例吧,我想大家都不陌生吧^-^单处理器(cpu)仅支持并发,即运行多个程序的时候并不是一起执行的,中间存在“时间切点”,单对多双处理器(cpu)同时支持并发和并行,每个线程各自执行自... 查看详情