HTTP中的GET和POST方法详解_http post get-程序员宅基地

技术标签: POST  GET  http  

一般来说GET是获取数据,POST是提交数据的。但是因为GET和POST都是HTTP的方法,HTTP又是基于TCP/IP的关于数据在万维网中如何让通讯的协议。从本质上讲,GET和POST都是HTTP请求,都是TCP链接,是无区别的。

但是HTTP协议既然有了这两个方法,就是为了在特定的情况下区分应用。

1、GET是获取数据,POST是提交数据的。
GET方法通常用于请求服务器发送某个资源,而且应该是安全的和幂等的。
仅仅是获取资源信息,就像数据库查询一样,不会修改和增加数据,不会影响资源的状态。

POST方法向服务器提交数据,将数据提交给服务器处理。POST是向服务器传输数据,数据会被重新提交,所以就会有对原有的数据造成伤害。向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。

安全的和幂等的。所谓安全的意味着该操作用于获取信息而非修改信息。幂等的意味着对同一个 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。换句话说,GET 请求一般不应产生副作用。从根本上讲,其目标是当用户打开一个链接时,可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的点赞应该通过 POST 请求实现,因为在点赞提交之后站点已经不同了,点赞数增多了。

2、考虑参数的位置:GET请求的参数位于url中,而POST请求的参数位于request body中。
这导致了三个问题,
一是GET请求的安全性不如POST请求;
二是GET的参数有长度限制,而POST没有;
三是GET的参数只允许ASCII字符,POST没有限制。

GET方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在Request Body内提交。使用 GET的时候,参数会显示在地址栏上,而 POST不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 GET;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 POST为好。

HTTP协议并没有对GET和POST的长度做限制,GET的最大长度限制是因为浏览器和web服务器限制了URL的长度
URL地址是有长度限制的(GET方式在通过URL提交数据),浏览器不同长度限制的具体数值也是不一样的。比如IE是2083字节。需要注意的是这些仅仅是URL地址栏的长度限制。
理论上来说POST的长度是没有限制的(POST方式,数据放置在Request body内提交),但是受服务器的配置限制或者内存大小的限制,造成了实际开发中POST也是有数据长度的限制的。

3、为什么GET比POST更快
1.POST请求包含更多的请求头
因为POST需要在请求的body部分包含数据,所以会多了几个数据描述部分的首部字段(如:content-type),这其实是微乎其微的。

2.最重要的一条,POST在真正接收数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据
POST请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送post请求头(第三次握手)
(4)服务器返回100 Continue响应
(5)浏览器发送数据

(6)服务器返回200 OK响应
GET请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送get请求头和数据(第三次握手)
(4)服务器返回200 OK响应

因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

1) GET与POST都有自己的语义,不能随便混用。
2) 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
3)并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

3.GET会将数据缓存起来,而POST不会 (GET在浏览器回退时是无害的,而POST会再次提交请求。GET会将请求参数放在请求的url中,回退操作实际上浏览器会从之前的缓存中拿结果;POST每次调用都会创建新的资源。)

可以做个简短的测试,使用ajax采用GET方式请求静态数据(比如html页面,图片)的时候,如果两次传输的数据相同,第二次以后消耗的时间将会在10ms以内(chrome测试),而POST每次消耗的时间都差不多。经测试,chrome和firefox下如果检测到GET请求的是静态资源,则会缓存,如果是数据,则不会缓存,但是IE什么都会缓存起来。

4.POST不能进行管道化传输
使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或HTTP connection reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。

但是这样的方式有一个问题:不安全,如果一个管道中有10个连接,在发送出9个后,突然服务器告诉你,连接关闭了,此时客户端即使收到了前9个请求的答复,也会将这9个请求的内容清空,也就是说,白忙活了……此时,客户端的这9个请求需要重新发送。这对于幂等请求还好(比如GET,多发送几次都没关系,每次都是相同的结果),如果是POST这样的非幂等请求,肯定是行不通的。
所以,POST请求不能通过管道的方式进行通信!很有可能,POST请求需要重新建立连接,这个过程不跟完全没优化的时候一样了么?所以,在可以使用GET请求通信的时候,不要使用POST请求,这样用户体验会更好,当然,如果有安全性要求的话,POST会更好。管道化传输在浏览器端的实现还需考证,貌似默认情况下大部分浏览器(除了opera)是不进行管道化传输的,除非手动开启!
总结:

GET POST
参数位置 url中 Request Body中
参数长度 有限制 无限制
参数编码 ASCII编码 无限制
后退/刷新 不重复提交,回退无害 重复提交,回退有害
安全性 参数暴露,不安全 安全
缓存 可以缓存 不可以缓存
书签 可以收藏为书签 不可以收藏为书签
历史 参数保存在浏览器历史 不保存在浏览器历史
请求包个数 1个 http header+data 2个 先 http header ,再data

根据这个总结你可以大胆放心的展开说了!

参考了很多博客还有自己理解添加整理,希望过些日子如果面试被问到会有帮助,也希望看到这篇博客的人天天开心。欢迎指正。

参考链接 :http://www.blogjava.net/honeybee/articles/164008.html
https://zhuanlan.zhihu.com/p/22536382
https://blog.csdn.net/cuiwkong/article/details/90312283
https://blog.csdn.net/zzk220106/article/details/78595108/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/scarificed/article/details/120197012

智能推荐

方法论之新公司入职准备步骤-程序员宅基地

文章浏览阅读347次。2019.06.06从职业生涯的第二家公司离职,因为第二家公司是行业内的世界第一,世界500强,学到的东西很多,公司氛围,同事之间的关系也比较简单,收获满满。当时离职被卡满满30天,最后一天还帮忙调试程序,然后下一个工作日就直接新的公司入职了。第三家公司算是中型公司,全球职工千人+。入职第三天开始做项目,节奏有点赶,第一个周末就加班调试。因为没有做好入职准备,刚开始还是比较被动的。重要的事还提前做...

shutil 用法-程序员宅基地

文章浏览阅读776次,点赞2次,收藏2次。https://www.mihaoyun.comhttps://www.jb51.net/article/211773.htm

使用IDEA学习java基础语法_用idea讲java-程序员宅基地

文章浏览阅读892次,点赞2次,收藏9次。开始使用IDEA创建java工程,两种方法 直接创建java工程 然后一路next,只需要修改工程名和路径即可 先新创建一个空项目,一路next后再选择Moudle创建java模块,如图 然后进行项目结构的配置,将图中两个位置进行设置 然后按照正常步骤即可 常使用的快捷键 快速复制一行ctrl+d 快速删除一行ctrl+y java的基础语法1.注释 ..._用idea讲java

el-button 显示与禁用_el-button禁用-程序员宅基地

文章浏览阅读8.4k次。el-button 的显示与隐藏iconfont 的引用_el-button禁用

STL-map按value排序_std::map 按value排序-程序员宅基地

文章浏览阅读953次。方法1 将pair存入vector排序在map中存储 <key, value> 键值对的数据结构是pair,简单直接的想法是将map中的pair复制一份存储到vector中,并重写compare函数根据second元素排序,就可以使用sort对该vector进行排序。代码实现#include <iostream>#include <algorithm>#include <string>#include <map>#include &l_std::map 按value排序

python列表中两个元素,多个元素进行位置互换,列表排序_change_list()-程序员宅基地

文章浏览阅读1.3w次,点赞7次,收藏18次。两个元素位置互换change_list = [6, 8]print(change_list)# 交换列表,以下两个均可# change_list[0], change_list[1] = change_list[1], change_list[0]change_list[1], change_list[0] = change_list[0], change_list[1] pri..._change_list()

随便推点

maven中pom文件配置_maven pom appname-程序员宅基地

文章浏览阅读2.4k次,点赞2次,收藏2次。pom配置基本如下:&lt;!-- 打包的机制,如pom,jar, maven-plugin, ejb, war, ear, rar, par,默认为jar --&gt; &lt;packaging&gt;war&lt;/packaging&gt; 定义常量,可采用${jdk.version}的方式引用配置jar包依赖配置:可在百度搜索maven repo..._maven pom appname

【前端学习笔记】JavaScript + jQuery + Vue.js + Element-UI_jquery2.14+vue2.5.16+element-plus-程序员宅基地

文章浏览阅读6.8k次,点赞23次,收藏156次。前端学习笔记JavaScriptVue.jsJavaScript基础语法(数据类型、字符串、数组、对象、Map、Set、iterable、函数基础)函数高级(变量作用域、解构赋值、方法、高阶函数、闭包、箭头函数、generator)摘自缪雪峰的博客的JavaScript个人笔记(3)Vue.js适合后端人员学习的Vue笔记(1)适合后端人员学习的Vue笔记(2)..._jquery2.14+vue2.5.16+element-plus

如何用DAP仿真器下载程序_dap下载器怎么连接-程序员宅基地

文章浏览阅读2.4k次。选择目标板,具体选择多大的Flash要根据板子上的芯片型号决定。秉火STM32开发板的配置是:F1选512K,F4选1M,我这里选的64k。擦除的Flash大小选择Sectors即 可,不要选择Full Chip,会非常慢。把仿真器用USB线连接至电脑,如果仿真器的灯亮则表示正常,可以使用。再把仿真器的另外-端连 接到开发板,给开发板上电,就可以通过软件KEIL或者IAR给开发板下载程序,仿真器见图1。单机LOAD按钮,进行下载,出现“Application running”下载成功。_dap下载器怎么连接

ACPI SpecV3.0学习总结_int15 getmemorymap-程序员宅基地

文章浏览阅读1.2k次。本文非原创文章,是对网上资料的整理,但忘了出处,在此未标明源地址表示抱歉。1.涉及的TABLESDTH &n..._int15 getmemorymap

Android Studio 引入aar文件_androidstudio引入aar包-程序员宅基地

文章浏览阅读2.5w次,点赞8次,收藏24次。方法一:在app目录下导入aar在app-libs目录下导入aar在app-build.gradle中配置repositories { flatDir { dir 'libs' } }implementation(name:'Test_debug', ext:'aar')构建项目,在External Libraries目录下会生成该依赖方法二、在项目根目录下导入aar(该方法更加实用,如果某一个library想依赖_androidstudio引入aar包

将SolidWorks模型文件导入Gazebo_solidworks模型导入ros-程序员宅基地

文章浏览阅读4.8k次,点赞7次,收藏87次。安装环境SolidWorks2016Gazebo7下载URDF插件下载链接:http://wiki.ros.org/sw_urdf_exporter默认路径安装到C盘,请根据自己的SolidWorks安装位置选择。_solidworks模型导入ros

推荐文章

热门文章

相关标签