计算机网络 GET 和 POST 的区别

01.GET请求场景

  • 在url中填写参数

    1
    2
    http://xxxx.xx.com/xx.php?params1=value1&params2=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
    3
    POST /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其他区别关系图

    img

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
    48
    public 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
    59
    public 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)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码。