精华内容
下载资源
问答
  • GET POST 的区别

    万次阅读 多人点赞 2019-04-07 22:30:29
    GET POST 的区别 二、HTTP 的请求报文 首先我们要解决的第一个问题是:GET POST 是什么? GET POST 其实都是 HTTP 的请求方法。除了这 2 个请求方法之外,HTTP 还有 HEAD、PUT、DELETE、TRACE...

    一、概述

    本文的内容源自其他博客的总结,属于笔者的读书笔记,结构如下:

    • HTTP 的请求报文
    • GET 方法的特点
    • POST 方法的特点
    • GET 和 POST 的区别

    二、HTTP 的请求报文

    首先我们要解决的第一个问题是:GET 和 POST 是什么?

    GET 和 POST 其实都是 HTTP 的请求方法。除了这 2 个请求方法之外,HTTP 还有 HEAD、PUT、DELETE、TRACE、CONNECT、OPTIONS 这 6 个请求方法。所以HTTP 的请求方法共计有 8 种,它们的描述如下所示:

    表格数据来源:菜鸟教程

    请求方法 描述
    GET 请求指定的页面信息,并返回实体主体。
    POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
    HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头。
    PUT 从客户端向服务器传送的数据取代指定的文档的内容。
    DELETE 请求服务器删除指定的页面。
    TRACE 回显服务器收到的请求,主要用于测试或诊断。
    CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
    OPTIONS 允许客户端查看服务器的性能。

    接下来我们解决第二个问题:请求方法如何使用?

    要解决这个问题,我们首先需要了解 HTTP 的请求报文结构:
    在这里插入图片描述
    可以看到 HTTP 的请求报文由三部分构成:

    • 请求行:由请求方法(Method)、URL 字段和 HTTP 的协议版本组成,注意其中的空格、回车符和换行符均不可省略,所以我们的请求方法实际上就是位于请求行中的了。
    • 请求头部:位于请求行之后,个数可以为 0~若干个,每个请求头部都包含一个头部字段名和一个值,它们之间用冒号 ":" 分隔,在最后用回车符和换行符表示结束。
    • 请求数据:如果请求方法为 GET,那么请求数据为空。它主要是在 POST 中进行使用,适用于需要填表单(FORM)的场景。

    我们通过一个实际的例子来看看 HTTP 的 GET 请求报文是什么样的,我们这里以访问 https://api.github.com/search/users?q=JakeWharton 为例,通过抓包我们得到的请求报文如下所示:

    GET /search/users?q=JakeWharton HTTP/1.1
    Host: api.github.com
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: _octo=GH1.1.1623908978.1549006668; _ga=GA1.2.548087391.1549006688; logged_in=yes; dotcom_user=GoMarck; _gid=GA1.2.17634150.1554639136; _gat=1
    

    我们重点看到请求行:

    GET /search/users?q=JakeWharton HTTP/1.1

    可以看到请求方法用的是 GET 请求,URL为 /search/users?q=JakeWharton,协议为 HTTP1.1。

    请求行下面部分全都是请求头部,我们可以看到 host 为 api.github.com,连接方式为长连接等信息。值得注意的是我们这个例子中是不存在请求数据的。


    接下来我们在来看一下 POST 请求的报文(该例子源自其他博客):

    POST / HTTP/1.1
    Host: www.wrox.com
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
    Gecko/20050225 Firefox/1.0.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 40
    Connection: Keep-Alive
    
    name=Professional%20Ajax&publisher=Wiley
    

    可以看到请求行中请求方法为 POST,URL 为空,协议版本也是 HTTP1.1。它和上面 GET 方法例子不一样的地方在于它的请求参数是位于请求数据中的,可以看到 name=Professional%20Ajax&publisher=Wiley 就是它的请求数据。并且我们要注意到在请求数据和请求头之间是空出一行的,这是必不可少的。

    三、GET 方法的特点

    1. 前面的例子:https://api.github.com/search/users?q=JakeWharton 就是一个非常典型的 GET 请求的表现形式,即请求的数据会附在 URL 之后(放在请求行中),以 ? 分割 URL 和传输数据,多个参数用 & 连接。

    2. 除此之外,根据 HTTP 规范,GET 用于信息获取,而且应该是安全和幂等的 。

    安全性指的是非修改信息,即该操作用于获取信息而非修改信息。换句话说,GET请求一般不应产生副作用,也就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。


    幂等性 (Idempotence) 则指的是无论调用这个URL 多少次,都不会有不同的结果的 HTTP 方法。而在实际过程中,这个规定没有那么严格。例如在一个新闻应用中,新闻站点的头版不断更新,虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。

    1. GET 是会被浏览器主动缓存的,如果下一次传输的数据相同,那么就会返回缓存中的内容,以求更快地展示数据。
    2. GET 方法的 URL 一般都具有长度限制,但是需要注意的是 HTTP 协议中并未规定 GET 请求的长度。这个长度限制主要是由浏览器和 Web 服务器所决定的,并且各个浏览器对长度的限制也各不相同
    3. GET 方法只产生一个 TCP 数据包,浏览器会把请求头和请求数据一并发送出去,服务器响应 200 ok(返回数据)。

    四、POST 方法的特点

    1. 根据 HTTP 规范,POST 表示可能修改变服务器上的资源的请求。例如我们在刷知乎的时候对某篇文章进行点赞,就是提交的 POST 请求,因为它改变了服务器中的数据(该篇文章的点赞数)。

    2. POST 方法因为有可能修改服务器上的资源,所以它是不符合安全和幂等性的。

    3. 从前面关于 POST 的请求报文也可以看出,POST 是将请求信息放置在请求数据中的,这也是 POST 和 GET 的一点不那么重要的区别。有一些博客的说法是 GET 请求的请求信息是放置在 URL 的而 POST 是放置在请求数据中的所以 POST 比 GET 更安全。其实这种说法很有问题,随便抓下包 POST 中的请求报文就暴露无疑了,这又何来安全之说?

    4. 因为 POST 方法的请求信息是放置在请求数据中的,所以它的请求信息是没有长度限制的。

    5. POST 方法会产生两个 TCP 数据包,浏览器会先将请求头发送给服务器,待服务器响应100 continue,浏览器再发送请求数据,服务器响应200 ok(返回数据)。这么看起来 GET 请求的传输会比 POST 快上一些(因为GET 方法只发送一个 TCP 数据包),但是实际上在网络良好的情况下它们的传输速度基本相同。

    五、GET 和 POST 的区别

    上面说了那么多 GET 方法和 POST 方法各自的特点,它们在外在的表现上似乎是有着诸多的不同,但是实际上,它们的本质是一样的,并无区别!!!

    这似乎有些不可思议,但是我们重新回想一下 GET 和 POST 是什么?它们是 HTTP 请求协议的请求方法,而 HTTP 又是基于TCP/IP的关于数据如何在万维网中如何通信的协议,所以 GET/POST 实际上都是 TCP 链接

    也就是说,GET 和 POST 所做的事其实是一样的,如果你给 GET 加上请求数据,给 POST 加上 URL 参数,这在技术上是完全可行的,事实上确实有一些人为了贪图方便在更新资源时用了GET,因为用POST必须要到FORM(表单),这样会麻烦一点(但是强烈不建议这样子做!!!)。


    既然 GET 和 POST 的底层都是 TCP,那么为什么 HTTP 还要特别将它们区分出来呢?

    其实可以想象一下,如果我们直接使用 TCP 进行数据的传输,那么无论是单纯获取资源的请求还是修改服务器资源的请求在外观上看起来都是 TCP 链接,这样就非常不利于进行管理。所以在 HTTP 协议中,就会对这些不同的请求设置不同的类别进行管理,例如单纯获取资源的请求就规定为 GET、修改服务器资源的请求就规定为 POST,并且也对它们的请求报文的格式做出了相应的要求(例如请求参数 GET 位于 URL 而 POST 则位于请求数据中)。

    当然,如果我们想将 GET 的请求参数放置在请求数据中或者将 POST 的请求数据放置在 URL 中,这是完全可以的,虽然这样子做并不符合 HTTP 的规范。但是这样子做是否能得到我们期望的响应数据呢?答案是未必,这取决于服务器的行为。

    以 GET 方法在请求数据中放置请求参数为例,有些服务器会将请求数据中的参数读出,在这种情况下我们依然能获得我们期望的响应数据;而有些服务器则会选择直接忽略,这种情况下我们就无法获取期望的响应数据了。

    所以,对于 GET 和 POST 的区别,总结来说就是:它们的本质都是 TCP 链接,并无区别。但是由于 HTTP 的规定以及浏览器/服务器的限制,导致它们在应用过程中可能会有所不同

    参考

    本篇博客参考自以下公众号、网站以及博客:

    WebTechGarden: 99%的人都理解错了HTTP中GET与POST的区别

    菜鸟教程:HTTP教程

    HTTP POST GET 本质区别详解 (转)


    希望这篇文章能对您有所帮助~ 有问题的话可以在评论区下方给我留言或者直接私信我。

    展开全文
  • get和post的区别

    2020-02-21 21:23:16
    get和post的区别

    get和post的区别

    • get的请求参数是放在URL里面的,可以被用户直观的看到. post的请求参数是放在请求体body里面的;
    • get请求的URL传参有长度限制,而post的请求长度是没有限制的;
    • get请求的参数只能是ascll码,所以中文需要URL编码,而post请求没有这个限制;

    综上: post相较于get更加的安全

    其实,get和post在本质上没有任何区别,他们都是HTTP协议中的请求方法.底层实现都是基于TCP/IP协议.上述的区别只是浏览器厂商根据约定,做出的现实而已.

    如果有兴趣的话,还可以了解了解RESTful API,HTTP请求和响应等.

    展开全文
  • GET和POST的区别

    千次阅读 多人点赞 2019-08-04 17:16:20
    GET和POST的区别 1 前言 最近看了一些同学的面经,发现无论什么技术岗位,还是会问到 get 和 post 的区别,而搜索出来的答案并不能让我们装得一手好逼,那就让我们从 HTTP 报文的角度来撸一波,从而搞明白他们的区别...

    GET和POST的区别

    1 前言

    最近看了一些同学的面经,发现无论什么技术岗位,还是会问到 get 和 post 的区别,而搜索出来的答案并不能让我们装得一手好逼,那就让我们从 HTTP 报文的角度来撸一波,从而搞明白他们的区别。

    2 标准答案

    分类 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 中。

    注意,并不是说标准答案有误,上述区别在大部分浏览器上是存在的,因为这些浏览器实现了 HTTP 标准。但是,前面列举的只是浏览器实现上的区别,而不是 get 和 post 的本质区别。

    3 GET 和 POST 报文上的区别

    先下结论,GET 和 POST 方法没有实质区别,只是报文格式不同

    GET 和 POST 只是 HTTP 协议中两种请求方式,而 HTTP 协议是基于 TCP/IP 的应用层协议,无论 GET 还是 POST,用的都是同一个传输层协议,所以在传输上,没有区别。

    报文格式上,不带参数时,最大区别就是第一行方法名不同

    POST方法请求报文第一行是这样的 POST /uri HTTP/1.1 \r\n

    GET方法请求报文第一行是这样的 GET /uri HTTP/1.1 \r\n

    是的,不带参数时他们的区别就仅仅是报文的前几个字符不同而已

    带参数时报文的区别呢? 在约定中,GET 方法的参数应该放在 url 中,POST 方法参数应该放在 body 中

    举个例子,如果参数是 name=qiming.c, age=22。

    GET 方法简约版报文是这样的

    GET /index.php?name=qiming.c&age=22 HTTP/1.1
    Host: localhost
    
    

    POST 方法简约版报文是这样的

    POST /index.php HTTP/1.1
    Host: localhost
    Content-Type: application/x-www-form-urlencoded
    
    name=qiming.c&age=22
    
    

    现在我们知道了两种方法本质上是 TCP 连接,没有差别,也就是说,如果我不按规范来也是可以的。我们可以在 URL 上写参数,然后方法使用 POST;也可以在 Body 写参数,然后方法使用 GET。当然,这需要服务端支持。

    4. 常见问题

    GET 方法参数写法是固定的吗?
    在约定中,我们的参数是写在 ? 后面,用 & 分割。

    我们知道,解析报文的过程是通过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。

    也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行,一种比较流行的写法是 http://www.example.com/user/name/chengqm/age/22。

    POST 方法比 GET 方法安全?
    按照网上大部分文章的解释,POST 比 GET 安全,因为数据在地址栏上不可见。

    然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。

    要想安全传输,就只有加密,也就是 HTTPS。

    GET 方法的长度限制是怎么回事?
    在网上看到很多关于两者区别的文章都有这一条,提到浏览器地址栏输入的参数是有限的。

    首先说明一点,HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因。

    浏览器原因就不说了,服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。

    POST 方法会产生两个TCP数据包?
    有些文章中提到,post 会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body。

    HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,header 和 body 不会分开发送。

    所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。

    5 talk is cheap show me the code
    如果对 get 和 post 报文区别有疑惑,直接起一个 Socket 服务端,然后封装简单的 HTTP 处理方法,直接观察和处理 HTTP 报文,就能一目了然

    
    #!/usr/bin/env python
    #-*- coding: utf-8 -*-
    
    import socket
    
    HOST, PORT = '', 23333
    
    
    def server_run():
        listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        listen_socket.bind((HOST, PORT))
        listen_socket.listen(1)
        print('Serving HTTP on port %s ...' % PORT)
        while True:
            # 接受连接
            client_connection, client_address = listen_socket.accept()
            handle_request(client_connection)
    
    
    def handle_request(client_connection):
        # 获取请求报文
        request = ''
        while True:
            recv_data = client_connection.recv(2400)
            recv_data = recv_data.decode()
            request += recv_data
            if len(recv_data) < 2400:
                break
    
        # 解析首行
        first_line_array = request.split('\r\n')[0].split(' ')
    
        # 分离 header 和 body
        space_line_index = request.index('\r\n\r\n')
        header = request[0: space_line_index]
        body = request[space_line_index + 4:]
    
        # 打印请求报文
        print(request)
    
        # 返回报文
        http_response = b"""\
    HTTP/1.1 200 OK
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>Hello, World!</title>
    </head>
    <body>
    <p style="color: green">Hello, World!</p>
    </body>
    </html>
    """
        client_connection.sendall(http_response)
        client_connection.close()
    
    
    if __name__ == '__main__':
        server_run()
    

    上面代码就是简单的打印请求报文然后返回 HelloWorld 的 html 页面,我们运行起来

    [root@chengqm shell]# python httpserver.py 
    Serving HTTP on port 23333 ...
    

    然后从浏览器中请求看看

    image

    打印出来的报文

    image

    然后就可以手动证明上述说法,比如说要测试 header 和 body 是否分开传输,由于代码没有返回 100 状态码,如果我们 post 请求成功就说明是一起传输的(Chrome/postman)。

    image

    又比如 w3school 里面说 URL 的最大长度是 2048 个字符,那我们在代码里面加上一句计算 uri 长度的代码

    
    
    ...
    # 解析首行
    first_line_array = request.split('\r\n')[0].split(' ')
    print('uri长度: %s' % len(first_line_array[1]))
    ...
    
    

    我们用 postman 直接发送超过 2048 个字符的请求看看

    image

    然后我们可以得出结论,url 长度限制是某些浏览器和服务器的限制,和 HTTP 协议没有关系。

    到此,我们可以愉快地装逼.

    参考:

    • 99%的人都理解错了HTTP中GET与POST的区别
    • 关于HTTP GET 和 POST
    • w3school: HTTP 方法:GET 对比 POST
    • wikipedia: 超文本传输协议
    • RFC 2068
    展开全文
  • Get和Post的区别

    2021-02-23 11:25:03
    get和post的区别总结 直观区别 get请求参数包含在url中,post通过request body传递参数。 get请求参数长度有限制(这是因为不同浏览器对url有限制的愿意),而post传参理论上是没有大小限制的。 get请求只能进行url...

    get和post的区别总结

    直观区别

    • get请求参数包含在url中,post通过request body传递参数。
    • get请求参数长度有限制(这是因为不同浏览器对url有限制的愿意),而post传参理论上是没有大小限制的。
    • get请求只能进行url编码,post支持多种编码方式。
    • get比post请求更不安全,因为它的参数直接暴露在url上面,所以不能用get传递敏感信息。

    本质上

    • 但本质上get和post是没有区别的。
    • get和post是HTTP协议中两种发送请求的方法,HTTP的底层是TCP/IP,所以get和post的底层也就是TCP/IP。
    • get和post都是TCP链接,所以他们能做的事情是一样的。

    那么get和post那些区别是从何而来呢?

    • 不同的浏览器和服务器对传输的参数进行了限制。
    • 浏览器通常都会限制url的长度在2kb个字节,服务器最多处理64kb大小的url,因此才产生的区别。

    get和post有一个本质上的区别

    • get发送请求产生一个TCP包,post产生两个TCP包
    • 用get方式请求,浏览器会把请求头和data一并返回;pos方式请求,浏览器先发header,服务器响应以后浏览器再返回data。
    展开全文
  • get post的区别

    2019-12-20 21:43:53
    get和post的区别: 第一:get和post都是http请求, 第二:get请求指定页面的信息,并返回实体主体, get是从服务器获取数据资源,post一般用于修改(更新)服务器上的的资源,是从服务器传送数据, get通过地址栏来...
  • get 和post 的区别

    2018-09-13 21:58:35
    一、get 和post 的区别 1)Get 是用来从服务器上获得数据,而Post 是用来向服务器上传递数据; 2)Get 将表单中数据按照variable=value 的形式,添加到action 所指向的URL 后面,并且两者使用“?”连接,而各个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,028
精华内容 4,411
关键字:

get和post的区别