关闭

浏览器中GET和POST请求的区别

标签: GETPOSTURL
4564人阅读 评论(0) 收藏 举报
分类:

在使用表单或者url提交数据时,我们经常要考虑到提交数据的方式,其中GET和POST介绍如下所示:

推荐链接:

1.  HTTP|GET 和 POST 区别?网上多数答案都是错的!

2.  你敢在post和get上刁难我,就别怪我装逼了


一、原理

(post和get在本质上是没有区别的,只不过在使用中进行了区别,下面主要说明的是使用中的区别)

          一般我们在浏览器输入一个网址访问网站都是GET请求;在使用FORM表单提交数据中,可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式。

          HTTP定义了与服务器交互的不同方法,其中最基本的四种:GET,POST,PUT,DELETE,HEAD,其中GET和HEAD被称为安全方法,因为使用GET和HEAD的HTTP请求不会产生什么动作。不会产生动作意味着GET和HEAD的HTTP请求不会在服务器上产生任何结果。但是安全方法并不是什么动作都不产生,这里的安全方法仅仅指不会修改信息。

         根据HTTP规范,POST可能会修改服务器上的资源的请求。比如CSDN的博客,用户提交一篇文章或者一个读者提交评论是通过POST请求来实现的,因为再提交文章或者评论提交后资源(即某个页面)不同了,或者说资源被修改了,这些便是“不安全方法”。

二、表现形式区别

在实际应用中的区别。首先,我们先看一下HTTP请求的格式:

如下面所示,为某一次在从浏览器获取的请求:

GET /index.html HTTP/1.1
Host: 127.0.0.1:10001
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

         
其中:第一行分别为method request-url version

            第二行到第八行为请求头部内容

            第九行为空行

            第十行为文本内容,由于没有值,所以显示空白

在HTTP请求中,第一行必须是一个请求行,包括请求方法,请求URL,报文所用HTTP版本信息。紧接着是一个herders小节,可以有零个或一个首部,用来说明服务器要使用的附加信息。在首部之后就是一个空行,最后就是报文实体的主体部分,包含一个由任意数据组成的数据块。但是并不是所有的报文都包含实体的主体部分,如上面所示就没有主体部分。

GET请求实例:上面举例内容就是GET请求,可总结为:

 get方式传参数
        GET /hello.html?name=tom HTTP1.1
        key: value
        key: value
        key: value
        .....
        \r\n

POST请求实例:
POST / HTTP/1.1
Host: 127.0.0.1:10001
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 22

id=1213&name=suguniang

可总结为:

    post方式传参
        POST /hello.html HTTP1.1
        key: value
        key: value
        key: value
        .....
        \r\n
        name=tom

接下来看看两种请求方式的区别:

1、GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后再传输。

POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。上面的id=1213&name=suguniang就是两个实际的传输数据键值对。因此,GET请求的数据会暴露在地址栏中,而POST请求则不会。

2、传输数据的大小

在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。

对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。

3、安全性

POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过GET请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,GET请求提交的数据还可能会造成Cross-site request frogery攻击,但是真正重要的数据在传的过程中还会更换协议http-->https,比如在网上支付的过程中

4、HTTP中的GET,POST,SOAP协议都是在HTTP上运行的

三、使用IDE获取请求内容POST与GET的请求内容

(1)如下所示,当我们使用最没有逻辑的代码获取结果时,分别如下:

GET方式:获取的值都在url中


POST方式:获取的值单独存在


由上面结果我们能够看到GET和POST是有区别的,GET方式传值在URL中,而POST传值在请求头后面再空一行处,这样,我们如果想要获取请求中传达的值时,就能够很快的获取,当然,上面这种代码实在太不负责任了,如果要在项目中获取最好采用下面的方法

如下所示为上面的代码:

package com.test.ch13;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class GetPostTest {
	public static void main(String[] args) {
		//1、创建一个服务器端的Socket[ServerSocket]
		ServerSocket ss=null;
		Socket s=null;
		BufferedInputStream bis=null;
		BufferedReader br=null;
		try
		{	ss=new ServerSocket(10001);
			//2、调用ServeSocket的accept方法,等待客户端发送过来的连接[Socket]
			s=ss.accept();
			//3、通过Socket获取输入流或者输出流
		     InputStream os=s.getInputStream();//使用输出流发送给客户端
		    //4、封装输入输出流,让读取速度更快
		     bis=new BufferedInputStream(os);
		     br=new BufferedReader(new InputStreamReader(bis));
		     //5、读,写数据
		     //在此处我们进行数据的读取
	    	                String line;
     		                line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
				line=br.readLine();
				System.out.println(line);
		} catch (IOException e) 
		{
			e.printStackTrace();
		}
		finally
		{
			//6、关闭资源
				try {
					br.close();
					s.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
		}
	}
}

(2)改进后的方法

package com.test.ch13;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class GetPostTest {
	public static void main(String[] args) {
		//1、创建一个服务器端的Socket[ServerSocket]
		ServerSocket ss=null;
		Socket s=null;
		BufferedInputStream bis=null;
		BufferedReader br=null;
		try
		{	ss=new ServerSocket(10001);
		//2、调用ServeSocket的accept方法,等待客户端发送过来的连接[Socket]
		s=ss.accept();
		//3、通过Socket获取输入流或者输出流
	        InputStream os=s.getInputStream();//使用输出流发送给客户端
	        //4、封装输入输出流,让读取速度更快
	        bis=new BufferedInputStream(os);
	        br=new BufferedReader(new InputStreamReader(bis));
	        //5、读,写数据
	        //在此处我们进行数据的读取
	    	String line;
		while(!"".equals((line=br.readLine()))){//在这里我们进行判断,是否还是文本行,如果是就进入while中
			System.out.println(line);
		}		
                if(br.ready()){
			char[] buf=new char[1024];
			int len = br.read(buf);
			String str=new String(buf, 0, len);
			System.out.println(str);
		}		
		System.out.println(br.ready());
		System.out.println(br.readLine());
		} catch (IOException e) 
		{
			e.printStackTrace();
		}
		finally
		{
			//6、关闭资源
				try {
					br.close();
					s.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
		}
	}
}
结果显示和上面的方法基本一致
3.get方式的访问和post方式的访问
    get方式访问
        浏览器地址栏直接输入地址访问
        超链接访问
        <image src="">访问图片
        外部js文件的引入
        外部css文件的引入
        表单提交数据method="get"
        在javascript代码中访问
        在ajax中访问
        使用jsp相关标签访问
    post方式访问
        表单提交数据method="post"
        ajax中设置本次请求为post方式

--

GET和POST还有一个重大区别,简单的说:
GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?
1. GET与POST都有自己的语义,不能随便混用。
2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

    


5
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:428076次
    • 积分:6231
    • 等级:
    • 排名:第4467名
    • 原创:228篇
    • 转载:106篇
    • 译文:0篇
    • 评论:57条
    博客专栏
    最新评论