一. 概述

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

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

二. HTTP 的请求报文

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

GET 和 POST 其实都是 HTTP 的请求方法。除了这 2 个请求方法之外,HTTP 还有 HEADPUTDELETETRACECONNECTOPTIONS 这 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)的场景。

    我们通过一个实际的例子来看看 HTTPGET 请求报文是什么样的,我们这里以访问 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

请求行下面部分全都是请求头部,我们可以看到 hostapi.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

可以看到请求行中请求方法为 POSTURL 为空,协议版本也是 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 是将请求信息放置在请求数据中的,这也是 POSTGET 的一点不那么重要的区别。有一些博客的说法是 GET 请求的请求信息是放置在 URL 的而 POST 是放置在请求数据中的所以 POSTGET 更安全。其实这种说法很有问题,随便抓下包 POST 中的请求报文就暴露无疑了,这又何来安全之说?

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

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

五. GET 和 POST 的区别

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

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

也就是说,GETPOST 所做的事其实是一样的,如果你给 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 的规定以及浏览器/服务器的限制,导致它们在应用过程中可能会有所不同。

推荐

文末

欢迎关注个人微信公众号:Coder编程

欢迎关注Coder编程公众号,主要分享数据结构与算法、Java相关知识体系、框架知识及原理、Spring全家桶、微服务项目实战、DevOps实践之路、每日一篇互联网大厂面试或笔试题以及PMP项目管理知识等。更多精彩内容正在路上~

新建了一个qq群:315211365,欢迎大家进群交流一起学习。谢谢了!也可以介绍给身边有需要的朋友。

文章收录至

Github: https://github.com/CoderMerlin/coder-programming

Gitee: https://gitee.com/573059382/coder-programming

欢迎关注并star~

[Java网络安全系列面试题] GET 和 POST 的区别在哪里?的更多相关文章

  1. [Java网络安全系列面试题] 说一说TCP和UDP的区别与联系?

    TCP TCP是Transfer Control Protocol(传输控制协议)的简称,是一种面向连接的保证可靠传输的协议. 在TCP/IP协议中,IP层主要负责网络主机的定位,数据传输的路由,由I ...

  2. [Java网络安全系列面试题]常见web攻击有哪些?

    搞Web开发离不开安全这个话题,确保网站或者网页应用的安全性,是每个开发人员都应该了解的事.本篇主要简单介绍在Web领域几种常见的攻击手段及Java Web中的预防方式. 1. XSS 1.1 什么是 ...

  3. Java多线程系列 面试题

    1. https://blog.csdn.net/jjj19891128/article/details/24393661  多线程经典面试题 2. https://blog.csdn.net/ll6 ...

  4. 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!

    目录 目录 string基础 Java String 类 创建字符串 StringDemo.java 文件代码: String基本用法 创建String对象的常用方法 String中常用的方法,用法如 ...

  5. 夯实Java基础系列6:一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别!

    目录 抽象类介绍 为什么要用抽象类 一个抽象类小故事 一个抽象类小游戏 接口介绍 接口与类相似点: 接口与类的区别: 接口特性 抽象类和接口的区别 接口的使用: 接口最佳实践:设计模式中的工厂模式 接 ...

  6. Java容器--2021面试题系列教程(附答案解析)--大白话解读--JavaPub版本

    Java容器--2021面试题系列教程(附答案解析)--大白话解读--JavaPub版本 前言 序言 再高大上的框架,也需要扎实的基础才能玩转,高频面试问题更是基础中的高频实战要点. 适合阅读人群 J ...

  7. Java程序员面试题集(1-50)(转)

    转:http://blog.csdn.net/jackfrued/article/details/17339393 下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和 ...

  8. Java 集合系列之一:JCF集合框架概述

    容器,就是可以容纳其他Java对象的对象.Java Collections Framework(JCF)为Java开发者提供了通用的容器 java集合主要划分为四个部分: Collection(Lis ...

  9. Java程序员面试题集(1-50

    下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最 ...

随机推荐

  1. Ubuntu 18.04 将gcc版本降级为5.5版本

    Remark: Polynomial algebra 程序由于版本问题只能在gcc 5.0 版本运行, 而ubuntu更新会将gcc 更新到7.0版本,出现冲突(报错:如下) collect2: er ...

  2. 生日Party 玄学多维DP

    题目描述 今天是hidadz小朋友的生日,她邀请了许多朋友来参加她的生日party. hidadz带着朋友们来到花园中,打算坐成一排玩游戏.为了游戏不至于无聊,就座的方案应满足如下条件:对于任意连续的 ...

  3. [CS充实之路] CS50 WEEK 1

    前言 大学电子专业,幸好自学了JAVA,遂有幸工作了三年,但这期间一直在焦虑,一个是基础不扎实的担心,另一个是未来方向的不确定.去年开始终于下定决心,一方面走一遍CS之路,巩固知识体系,另一方面部署自 ...

  4. Python第七章-面向对象

    面向对象编程基础 一.面向对象概念 1.1 什么是面向过程 ​ 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了. ​ 生活中的的例子举例. 1.2 ...

  5. 二维线段树 poj-2155

    题意:t组样例 ,输入 n,m,表示n*n的矩阵进行m次操作 ,C: 输入两个坐标 ,组成的矩形 进行取反操作 ,Q:对输的坐标位置输入其值. 思路:一开始想的是用1000(表示x轴)个线段树(对每段 ...

  6. iOS 13DarkMode暗黑模式

    iOS 13系统的iPhone 在设置-->显示与亮度 -->选择深色 即开启暗黑模式 1.暗黑模式关闭 1.1 APP开发未进行暗黑适配,出现顶部通知栏字体颜色无法改变始终为白色.可以全 ...

  7. 【Python3爬虫】反反爬之破解同程旅游加密参数 antitoken

    一.前言简介 在现在各个网站使用的反爬措施中,使用 JavaScript 加密算是很常用的了,通常会使用 JavaScript 加密某个参数,例如 token 或者 sign.在这次的例子中,就采取了 ...

  8. HTML+CSS:css定位详解之相对定位、绝对定位和固定定位

    相对定位 如果想为元素设置层模型中的相对定位,需要设置position:relative;,它还是会占用该元素在文档中初始的页面空间,通过left.right.top.bottom属性确定元素在正常文 ...

  9. 怎样让scratch里的人物两腿走动

    需要人物角色至少有两个“造型”,表现走路时的两个动作.以默认的“小猫”觉色为例,它有两个“造型”,可以用来表现奔跑的动作. 但是要想让小猫跑起来,需要脚本来实现,简单跑动脚本如下 scratch学习视 ...

  10. grub2手动引导linux

    仅需要三个命令 1.set root=(hd*,gpt*) hd*为系统所在磁盘,从0开始: gpt为磁盘分区表格式,*为第几分区,mbr分区表为msdos*: 2.linux /boot/vmlin ...