Web 开发:http 消息的 GET 和 POST 有什么区别?
1.前言
最近看了一些同学的采访,发现无论处于什么技术岗位,还是被问到get和post的区别以及答案他们发现他们情不自禁地认为我们很好。很酷,我们从HTTP消息的角度来看一下,了解它们的区别。
2。标准响应
在开始之前,让我们看看 w3school 的标准响应是什么样的:GET 与 GET。邮政。标准的回答都很好,但如果你在采访中把下面的表格扔到面试官面前,你可能是在自欺欺人,而不是炫耀。
类别 | 培训 | POST |
---|---|---|
后退按钮/更新 | 无害 | 数据将重新发送给用户(数据重新发送)。 |
书签 | 可添加书签 | 不可添加书签 |
缓存 | 可缓存❝ application/x-www-form-urlencoded | application/x-www-form-urlencoded 或多部分/表单-数据。对二进制数据使用多种编码。 |
历史记录 | 参数保存在浏览历史记录中。 | 参数不会保存在浏览器历史记录中。 |
数据长度限制 | 是。发送数据时,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= Chengqm,age=22。
GET 方法消息的简化版如下:
GET /index.php?name=qiming.c&age=22 HTTP/1.1
Host: localhost
POST 方法的简化版是这样我们知道这两种方式本质上都是TCP连接,没有什么区别,所以不按照规范也没关系。我们可以将参数写入URL,然后方法使用POST;我们也可以将参数写入Body,然后该方法使用GET。当然,这需要服务器端的支持。
4。常见问题
GET方法参数的写法是否固定?
在约定中,我们的参数是?并用 & 分隔。
我们知道解释消息的过程就是拿到TCP数据,利用常用的工具等工具从数据中提取出header和body,然后提取出参数。
也就是说,如果服务器能够解释的话,我们自己可以就参数的写入方式达成一致。更流行的拼写是http://www.example.com/user/name/hengqm/age/22。
POST 方法比 GET 方法更安全吗?
网上大多数文章都解释说POST比GET更安全,因为数据在地址栏中不可见。
但是从传输的角度来看它们都是不安全的,因为HTTP是在网络上以明文形式传输的,只要在网络节点捕获到数据包,就可以完全接收到数据报文。
确保传输安全的唯一方法是加密,即HTTPS
。
GET方法的长度限制是多少?
我在网上看到很多关于两者区别的文章。有人提到,在浏览器地址栏中输入的参数是有限的。
首先说明一下,HTTP协议对于body和URL没有长度限制。大多数 URL 限制来自浏览器和服务器。
浏览器的原因我就不说了。服务器消耗大量资源来处理长 URL。为了性能和安全性(防止恶意创建攻击所需的长 URL),URL 的长度将受到限制。
POST 方法是否生成两个 TCP 数据包?
有些文章提到帖子将标题和正文分开发送。它首先发送标头,服务器在发送正文之前返回状态代码 100。
HTTP协议没有明确规定POST生成两个TCP数据包,实际测试(Chrome)发现header和body没有分开发送。
因此,单独发送 header 和 body 是某些浏览器或框架的请求方式,并不是不可避免的 post 行为。
5。空谈是廉价的,给我看看你的代码
如果你对接收和发送消息的区别有任何疑问,只需启动一个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...
然后让浏览器看到打印的消息手动验证上面的语句,例如测试header和body是否分开传输。由于代码不会返回100的状态码,所以如果发送请求成功,就意味着会一起转发(Chrome/postman)。
再举个例子,w3school说URL的最大长度是2048个字符,那么我们在代码中添加一段代码来计算uri的长度
...
# 解析第一行 _ray第一行=请求。 split('\r\n')[0].split(' ')
print('uri length: %s' % len(first_line_array[1]))
...
让我们使用邮递员直接发送超过 2048 个字符的请求来查看
。由此我们可以得出结论,url长度限制是某些浏览器和服务器的限制,与HTTP协议无关。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。