GET 和 POST 是 HTTP 协议中的两种发送请求的基本方法,对于前端开发者而言,几乎每天都在使用它们,再熟悉不过了,一般也都能说出几点两者的区别。

如果面试中被问到这个问题,先回答一下几点,肯定是不会有错的:

  1. GET 参数通过 URL传值,参数可见且不够安全,不能用来传递敏感信息,而 POST 参数放在 Request body 中,参数不可见,相对而言比较安全;
  2. GET 请求在 URL 中传送的数据大小是有限制的(一般不超过2k-4k,取决于浏览器),而 POST 请求中的数据大小长度根据后台配置文件设定,理论上没有限制;
  3. GET 在浏览器回退时是无害的,而 POST 在浏览器回退时会再次提交请求;(GET 会将请求参数放在请求的 URL 中,回退操作实际上浏览器会从之前的缓存中拿结果,POST 每次调用都会创建新的资源)
  4. GET 请求会被浏览器主动 cache,而 POST 除非手动设置,否则不会;(浏览器缓存分为强缓存和协商缓存)
  5. GET 产生的 URL 地址可以被 Bookmark,而 POST 不可以;(GET 请求会把参数带到 URL 中,可以此保存浏览器书签)
  6. GET 请求参数会被完整地保留在浏览器历史记录里,而 POST 中的参数不会被保留;(道理同上)
  7. GET 请求只能进行 URL 编码,而 POST 支持多种编码方式;
  8. 对参数的数据类型,GET 只接受 ASCII 字符,而 POST 没有限制;(URL 是 HTTP 的一个首部,根据约定,一定是 ASCII 字符的)
  9. GET 请求产生一个 TCP 数据包,而 POST 请求产生两个数据包;

但是!

这就结束了吗?

NO!NO!NO!

想要拿到高薪,得说出一点别人不知道的东西,气场这块要拿捏地死死的。

抛开固有印象,我们重新来审视一下 GET 和 POST,会发现它们本质上没有区别!

我们知道 GET 和 POST 是 HTTP 协议中的两种发送请求的方法,而 HTTP 是基于 TCP/IP 的关于数据在万维网中如何通信的协议

HTTP 的底层是 TCP/IP,所以 GET 和 POST 的底层也是 TCP/IP。也就是说, GET 和 POST 都是 TCP 连接(这应该可以算是两者的相同点)。

换句话说,GET 和 POST 能做的事情是一样的,在技术上完全可以给 GET 请求 加上 Request body,给 POST 请求带上 URL 参数。

但是存在也不代表着一定合理。

在万维网世界中,TCP就像汽车,负责用来运输数据,但路上的汽车不会只有一辆的,而为了维护交通的高效运行,交通规则 HTTP 应运而生。HTTP 给汽车设定了几种服务类别,有 GET、POST、PUT、DELETE 等。HTTP 规定,当执行 GET 请求时,要给该车贴上 GET 标签,并且把要传输的数据放在车顶上(url 中)以方便记录;当执行 POST 请求时,要给该车贴上 POST 标签,并且为了安全把要传输的数据放在车厢里(Request body 中)。

当然规定是规定,你要非要在 GET 的时候偷偷在车厢里放一点货,或者在 POST 的时候把货往车顶上放,谁也拦不住你,只是会让别人觉得你是个憨憨,不跟你玩。

所以,HTTP 只是个行为准则,而 TCP 才是 GET 和 POST 怎么实现的基本。

上面我们了解了 HTTP 对 GET 和 POST 参数的传输渠道(url 还是 Request body)提出了要求,但我们还知道,两种请求的还对参数大小做出了限制,这又是怎么回事呢?

在万维网世界中,还有另一个重要角色:运输公司。不同的浏览器(发起 HTTP 请求)和服务器(接收 HTTP 请求)就是不同的运输公司。虽然理论上,可以在车顶无限堆放货物(url 中无限加参数),但是装货和卸货也是要成本的,运输公司要核算成本和控制风险,所以他们会限制单次运输量,数据量太大对浏览器和服务器都是很大的负担。

所以,大多数浏览器会限制 url 长度最多在 2k 个字节,大多数服务器最多处理 64k 大小的 url。如果你用 GET 服务,在 Request body 中偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你读出数据,但有些服务器会直接忽略。所以还是不要这样操作了。

现在我们知道,GET 和 POST 本质上就是 TCP 连接,并无差别,只不过由于 HTTP 的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

说道这里,GET 和 POST 要说的也就差不多了。等等,或许你注意到了,上文中我特意给第9点加粗了,也就是:GET 请求产生一个 TCP 数据包,而 POST 请求产生两个数据包。

这是怎么回事呢?

对于 GET 请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200;

而对 POST 请求,浏览器先发送 header,服务器响应 100,浏览器再发送 data,服务器响应 200。

可以看出,POST 请求需要两步,而 GET 请求仅需一步,很明显 GET 的用时更短,效率更高。但如果你想用 GET 来代替 POST 来优化网站性能的话,还是需要谨慎的,以为:

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

以上就是我总结的关于 GET 和 POST 的关系,望诸君雅正。

GET和POST两者的区别的更多相关文章

  1. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

  2. jquery和Js的区别和基础操作

    jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...

  3. 【原】nodejs全局安装和本地安装的区别

    来微信支付有2年多了,从2年前的互联网模式转变为O2O模式,主要的场景是跟线下的商户去打交道,不像以往的互联网模式,有产品经理提需求,我们帮忙去解决问题. 转型后是这样的,团队成员更多需要去寻找业务的 ...

  4. 探究@property申明对象属性时copy与strong的区别

    一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...

  5. X86和X86_64和X64有什么区别?

    x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为&qu ...

  6. Java中Comparable与Comparator的区别

    相同 Comparable和Comparator都是用来实现对象的比较.排序 要想对象比较.排序,都需要实现Comparable或Comparator接口 Comparable和Comparator都 ...

  7. MySQL中interactive_timeout和wait_timeout的区别

    在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR (HY000): Lost connection to MySQL server ...

  8. 设置line-height:1.5和line-height:150%或者line-height:150px的区别

    直接正题: 看一下line-height可能的值: 其实可以分为两类: (1)不带单位的(如line-height:1.5),这种是推荐使用的: (2)带单位的(如line-heigth:30px/1 ...

  9. C#中Length和Count的区别(个人观点)

    这篇文章将会很短...短到比你的JJ还短,当然开玩笑了.网上有说过Length和count的区别,都是很含糊的,我没有发现有 文章说得比较透彻的,所以,虽然这篇文章很短,我还是希望能留在首页,听听大家 ...

  10. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

随机推荐

  1. Linux slabtop命令——显示内核片缓存信息

    Linux内核需要为临时对象如任务或者设备结构和节点分配内存,缓存分配器管理着这些类型对象的缓存.现代Linux内核部署了该缓存分配器以持有缓存,称之为片.不同类型的片缓存由片分配器维护. slabt ...

  2. docker(5)docker运行web应用

    前言 前面我们运行的容器并没有一些什么特别的用处. 接下来让我们尝试使用 docker 构建一个 web 应用程序. 我们将在docker容器中运行一个 Python Flask 应用来运行一个web ...

  3. Pytest(5)美化插件进度条pytest-sugar

    前言 在我们进行自动化测试的时候,用例往往是成百上千,执行的时间是几十分钟或者是小时级别.有时,我们在调试那么多用例的时候,不知道执行到什么程度了,而pytest-sugar插件能很好解决我们的痛点. ...

  4. 如何安装Python 3.9.1?

    首先打开浏览器输入网址:https://www.python.org或者通过百度搜索python进入Python官网. 选择Downloads,弹出最新版本下载链接,当前版本为3.9.1,如图所示: ...

  5. Java线程八锁

    package com.atguigu.juc1205; import java.util.concurrent.TimeUnit; class Phone//Phone.java ---> P ...

  6. Codeforces Round #647 (Div. 2) B. Johnny and His Hobbies(枚举)

    题目链接:https://codeforces.com/contest/1362/problem/B 题意 有一个大小及元素值均不超过 $1024$ 的正整数集合,求最小正整数 $k$,使得集合中的每 ...

  7. 2020 年百度之星·程序设计大赛 - 初赛一Dec 简单dp

    题意: Problem Description 初始有 a, ba,b 两个正整数,每次可以从中选一个大于 1 的数减 1,最后两个都会减到 1,我们想知道在过程中两个数互质的次数最多是多少. Inp ...

  8. hdu5135 Little Zu Chongzhi's Triangles

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submissi ...

  9. C++ part3

    函数和const references: C++中const用于函数重载 有些情况可以重载,有些不行,具体看↑. 隐式类型转换 references: nowcoder 对于内置类型,低精度的变量给高 ...

  10. Gym 101480I Ice Igloos(思维乱搞)题解

    题意:给个最多500 * 500的平面,有半径最多不为1的n个圆,现在给你1e5条线段,问你每条线段和几个圆相交,时限10s 思路: 因为半径<1,那么我其实搜索的范围只要在线段附近就好了.x1 ...