文章目录
- 一、认识什么是 HTTP 协议
- 二、HTTP 抓包工具
- 1.了解使用哪种工具
- 2.了解抓包工具抓包的原理
- 3.简单使用抓包工具
- 三、解释 HTTP 中的报文格式
- 1.认识 URL
- 2. 认识 HTTP 请求
- 解释首行 "方法"
- 解释 请求头(header)
- 空行
- body
- 3、总结
一、认识什么是 HTTP 协议
HTTP 全称为 “超文本传输协议” 是一个应用层协议。
通俗的来讲,HTTP 就是 浏览器和服务器之间交互的桥梁。
HTTP 往往是基于传输层的 TCP 协议来实现的。
也就是说,HTTP 请求,本质上就是给 TCP socket 内写了一个符合 HTTP 格式的字符串。
HTTP 的工作过程,大致上如下图所示:
二、HTTP 抓包工具
1.了解使用哪种工具
为了可以更直观的见到 HTTP 协议的交互详细过程,在这里我们可以借助一个 第三方工具 来看到。称为 “抓包”。
在这里,本人使用的工具是 Fiddler。
这里是官方的下载地址:Fiddler 抓包工具
使用注意事项:
filder 本质上是一个代理程序,使用时需要注意下面两点。
- 可能会和别的代理程序产生冲突,使用时要注意关闭其他代理程序(包括浏览器的插件)
- 想要正确的实现抓包,还需要开启一个 https 功能。
fider 在默认情况下是不能抓 https 的包的,这里需要手动启动一下。如图:
2.了解抓包工具抓包的原理
在上面我已经提到过,这个抓包工具本质上是一个代理。在这里,代理起到的作用就是一个中间传话人。
如图:
在这个过程之中,浏览器和服务器之间进行了那些信息交流。这个中间的传话人就可以将信息记录下来。
代理分为两种,正向、反向
正向代理:代表着客户端的代理,称之为正向代理。
反向代理:代表着服务器的代理,称之为反向代理。
3.简单使用抓包工具
这里,我通过访问 百度 的页面,简单进行抓包操作。
如图所示,这个蓝色的字符串就是一个 html 页面。
上面的这么多结果,就是浏览器在访问搜狗主页时,产生的 HTTP 请求。浏览器打开一个页面,对应的请求可能是一个,也可能是多个。
双击蓝色链接,此时,在工具栏的右侧上半部分,选中 Raw ,在此处,就可以看到最原始的效果。
观察这里的抓包结果,可以看到,这里是 HTTP 请求,其实是一个文本行格式的数据。相较于 tcp 这样的 二进制 格式,就更方便让用户进行观察。
如图所示,这里是 响应数据,这些数据本身也是文本,但是,有的服务器为了节省带宽,在此处会将响应进行压缩。(变为二进制)
这里的文本内容就是百度首页,html 中的内容。
三、解释 HTTP 中的报文格式
在前面,我们已经介绍了 TCP 、UDP 这两个协议数据报。所以,要学习一个新的协议,最主要要了解的就是 报文格式!
如上图所示,这就是抓包工具获取到的 首行信息。
这里包含着三个部分,之间使用空格进行区分。
- GET: HTTP 的方法。
- https://www.baidu.com/: URL 也就是俗称的网址。
- HTTP/1.1: 版本号。
1.认识 URL
如上图所示,这就是一个基本的 URL 。
但是,需要注意的是,URL 并不是 HTTP 专属的。很多协议都可以使用 URL。
例如:在 jdbc 中,setURL
需要标注出 数据库服务器 的位置就需要:
setURL("jdbc:mysql://127.0.0.1:3306/JDBCtest?characterEncoding=utf-8&useSSl=false");
在上面的 URL 中,最关键的四个部分是:
1.域名 / IP
2.端口号
3.带层次的路径
4.查询字符串
下面我通过一个比较形象的例子来让我们更加容易理解:
URL 中的部分情况解释
到这里,我们可能会有一些疑问。在前面我们进行抓包时,抓取到的是 https://www.baidu.com/
我们发现上面的 URL 格式存在着差异。
到此,我们要知道一个新的概念:一个 URL 中有几个比较特殊的部分。
- 端口号:这个信息是可以省略的。在省略是,浏览器会默认提供端口。
对于 http,默认端口是 80;
对于 https,默认端口是 443. - 路径:这里的 / 也是一个路径,这里没有省略,只是有点短。。。
这里代表的是 “根目录”,是 http 服务器的根目录,http 服务器是系统上的一个进程。这个目录里的资源都可以让外界进行访问。
这里我们可以访问一下百度贴吧,看看其中的不同之处。
此时我们随便点进去一个帖子
查询字符串,是以 ?开头,以键值对的方式组织。
键值对之间使用 & 分割。
键和值之间使用 = 分割。
2. 认识 HTTP 请求
在介绍 HTTP 请求之前,我们先要了解 HTTP 请求的四个部分。
- 首行
- 请求头(header)
- 空行
- 正文(body)
解释首行 “方法”
所谓 “方法” ,就是阐述了此次请求的语义——(想要做什么)。
方法种类大致如下:
这里的方法看似很多,但是在实际开发中,最常用的就是 GET 和 POST 两个。
- GET 请求
就是在浏览器的地址栏中直接输入 url。
通过抓包工具我们可以的到下面的信息:
- POST 请求
对于这个请求,最典型的就是登录操作,在登录跳转时,就会涉及到 POST 请求。还有另一个就是上传文件操作。
通过抓包操作,我们可以得到下面的信息:
这里的 body 中的内容是程序员自定义的。
观察上面的信息,我们就可以发现,如果是 GET 请求,一般没有 body 。而如果是 POST 请求,一般有 body。
经典面试问题
GET 和 POST 之间的典型区别:
- GET 也可以向服务器传递一些信息,GET 传递的信息一般都是放在 query string。
而 POST 则是通过 body 传递。- 语义上存在着差别
GET 请求一般是用在服务器获取数据
POSt 请求一般是用来给服务器传递数据- GET 通常会被设定为 幂等 的。
(所谓 幂等 就是相同的输入,得到的结果也是确定的)
POST 不要求幂等- GET 可以被缓存
POST 一般不能被缓存
解释 请求头(header)
如上图所示,这里 header 中就是 一些键值对。这些键值对是 HTTP 事先定义好的,有着特定的含义。
- Host
Host 这里的 地址 和 端口 ,用来描述你最终要访问的目标。
这个内容大概率和 URL 中的是一样的,也有不同的情况。
- Content-Length & Content-Type
上面的两个关键字,前者,表示 body 中的数据长度。后者,表示 body 中的数据格式。
注意:
要使用这两个关键字的前提必须是有 body 。
如果是 GET ,则没有 body。
如果是 POST,有 body 则必须要有这两字段。
这里通过一个简单图示来解释一下:
- User-Agent(简称 UA)
如图所示:
这个字段,描述的是 浏览器和操作系统的版本
目前,这个字段主要是用来区分 PC 和 移动端。通过 User-Agent 来进行大的区分。
- Referer
这个字段,描述的是当前页面的 “来源”。
这个字段的主要作用就是 “统计” 和 “防盗链”。
需要注意的是,如果直接通过地址栏输入地址,或者点击收藏夹,这里是没有 referer 的。
上面说到,这个字段中的有一个作用是 “统计”。
在这里,统计的意思就是,当浏览器想 web 服务器发送请求时,来告诉服务器这个页面是通过哪一个链接来的,从而根据这个信息来 统计流量
了解 “劫持” 现象
HTTP 本身是明文传输的,很容易就可以获取到请求内容,所以也是有办法篡改内容的,此时如果将 referer 修改,流量就会发生改变,呢么此时就发生了 劫持。
- Cookie
这个字段也是一个非常关键的一个属性。
我们需要注意一个关键点:网页,默认是不允许访问计算机硬盘的。
所以,在本质上,这是浏览器给网页提供的 本地存储数据的机制!
cookie 就是浏览器对于访问硬盘做出了限制。
观察上图,我们会发现,cookie 是通过键值对的形式对数据进行组织。
问题 1
Cookie 从哪里来?
Cookie 中的数据来自于服务器,服务器会通过 HTTP 响应的报头部分(Set-Cookie 字段),来决定 Cookie 需要存储什么东西。
问题 2
Cookie 将数据存放在哪?
这里可以认为数据 存放在浏览器,存放在硬盘中。
Cookie 存在是,是按照 浏览器 + 域名 维度进行细分的。不同的浏览器,各自存放 Cookie。同一个浏览器的不同域名,对应不同的 Cookie。
Cookie 内部存放的不止是键值对。同时还有 过期时间。(在很多网站中,登陆一次之后,会自动记录一段时间的登录状态)
问题 3
cookie 要回到哪里?
cookie 中的信息会回到服务器中。
在客户端这边,会通过 cookie 来保存当前用户使用的中间状态。
当客户端访问浏览器的时候,就会自动的将 cookie 中的内容带入到请求中。 此时,服务器就能知道现在客户端是什么样子。
形象的来看:
cookie 就像是 服务器 在 浏览器 这里制造的一个寄存处一样。
举个栗子:
比如说,我们去学校的图书阅览室的电脑上进行了登录操作。此时的登录状态就保存到了cookie之中。
cookie 是有保存时间的。
在这个时间内,当我们去访问时,浏览器就会在请求后端信息时,同时将 cookie 传递给后端进行解析。此时,就不需要从新登陆了。
但是如果超过这个保存时间,后端就会要求重新登陆了。网站越敏感,cookie 过期的时间就会越短。
空行
对于空,我想应该没有什么需要解释的。但是,这里有一个值得思考的问题:
为什么 HTTP 报文中要存在空行?
其实这个原因有两点:
- HTTP 协议没有规定报头部分的键值对有多少个,空行在这里的作用就是报头的结束标记。
- HTTP 在传输层所依赖的是 TCP 协议,是面向字节流的。 如果没有这个空行就会出现 “粘包” 问题。
body
这里的正文内容一般都是 程序员自己设定的。其中的信息是以键值对的形式存才的。
键值对之间使用 & 进行分割。
键和值之间使用 = 进行分割。
3、总结
在上面,我已经将 HTTP 协议格式中的各个部分进行简单的说明,下面通过这张图片,我们可以更加直观和系统的看到 HTTP 协议在 浏览器 和 服务器 之间的交互。