计算机网络 GET 和 POST 的区别
01.GET请求场景
在url中填写参数
1
2http://xxxx.xx.com/xx.php?params1=value1¶ms2=value2
https://api.douban.com/v2/book/search?tag=文学&start=0&count=30有关 GET 请求的其他一些注释:
- GET 请求可被缓存
- GET 请求保留在浏览器历史记录中
- GET 请求可被收藏为书签
- GET 请求不应在处理敏感数据时使用
- GET 请求有长度限制
- GET 请求只应当用于取回数据
02.POST请求场景
请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:
1
2
3POST /test/demo_form.asp HTTP/1.1
Host: taobao.com
name1=value1&name2=value2有关 POST 请求的其他一些注释:
- POST 请求不会被缓存
- POST 请求不会保留在浏览器历史记录中
- POST 不能被收藏为书签
- POST 请求对数据长度没有要求
03.GET和POST区别
GET和POST区别
- Get请求的参数是直接放在url后面的,而Post请求是放在请求体中的
- Get请求参数拼接的url的长度会根据浏览器的不同实现有一定限制,而Post请求参数长度没有限制
- Get请求方便测试,直接输入地址即可,而Post请求不方便测试,需要借助代码或者工具进行发送
注意误解:
- Get传递数据上限XXX;胡说。有限制的是浏览器中的url长度,不是Http协议,移动端请求无影响。Http服务器部分有限制的设置一下即可。
- HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。
GET产生一个TCP数据包;POST产生两个TCP数据包。
- 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
- 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
- POST需要两步,时间上消耗一定要多一点吗?看起来GET比POST更有效吗?答案是不一定的。
- GET与POST都有自己的语义,不能随便混用。
- 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
- 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
登陆或者购物添加商品使用get还是post?
- 使用post请求,因为针对这种涉及隐私的请求,应该将请求参数防到请求体中,避免被窃取。
关于GET和POST其他区别关系图
04.GET请求代w码
代码如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48public static String get(String url) {
HttpURLConnection conn = null;
try {
// 利用string url构建URL对象
URL mURL = new URL(url);
// 调用URL的openConnection()方法,获取HttpURLConnection对象
conn = (HttpURLConnection) mURL.openConnection();
// 设置请求方法为get
conn.setRequestMethod("GET");
// 设置读取超时为5秒
conn.setReadTimeout(5000);
// 设置连接网络超时为10秒
conn.setConnectTimeout(10000);
// 调用此方法就不必再使用conn.connect()方法
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
//返回从打开的连接读取的输入流
InputStream is = conn.getInputStream();
String response = getStringFromInputStream(is);
return response;
} else {
throw new NetworkErrorException("response status is "+responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return null;
}
private static String getStringFromInputStream(InputStream is) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
// 模板代码 必须熟练
byte[] buffer = new byte[1024];
int len = -1;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
is.close();
// 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
String state = os.toString();
os.close();
return state;
}
05.POST请求代码
代码如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59public static String post(String url, String content) {
HttpURLConnection conn = null;
try {
// 创建一个URL对象
URL mURL = new URL(url);
// 调用URL的openConnection()方法,获取HttpURLConnection对象
conn = (HttpURLConnection) mURL.openConnection();
// 设置请求方法为post
conn.setRequestMethod("POST");
// 设置读取超时为5秒
conn.setReadTimeout(5000);
// 设置连接网络超时为10秒
conn.setConnectTimeout(10000);
// 设置此方法,允许向服务器输出内容
conn.setDoOutput(true);
// post请求的参数
String data = content;
// 获得一个输出流,向服务器写数据,默认情况下,系统不允许向服务器输出内容
// 获得一个输出流,向服务器写数据
OutputStream out = conn.getOutputStream();
out.write(data.getBytes());
out.flush();
out.close();
// 调用此方法就不必再使用conn.connect()方法
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
InputStream is = conn.getInputStream();
String response = getStringFromInputStream(is);
return response;
} else {
throw new NetworkErrorException("response status is "+responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();// 关闭连接
}
}
return null;
}
private static String getStringFromInputStream(InputStream is) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
// 模板代码 必须熟练
byte[] buffer = new byte[1024];
int len = -1;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
is.close();
// 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
String state = os.toString();
os.close();
return state;
}
06.浏览器对url限制
- 注意这句话是错的:
- Get传递数据上限XXX;胡说。有限制的是浏览器中的url长度,不是Http协议,移动端请求无影响。Http服务器部分有限制的设置一下即可。
- 业界不成文的规定是
- 大多数浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。
07.请求的安全性
- POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。
- 上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码。