目录
一、HTTP协议工作过程
二、 协议格式
1、抓包工具Fiddler
2、HTTP请求格式
3、HTTP响应格式
4、HTTP协议格式总结
三、HTTP请求(Request)
1、URL
(1)URL基本格式
(2)URL实例 (如何查看域名对应的IP地址)
(3)URL encode / decode
2、方法
(1)GET 方法
(2)POST 方法
3、GET 方法和 POST 方法的区别
(1)语义上的区别
(2)习惯用法上的区别
(3)等幂性上的区别
(4)是否能缓存上的区别
3、请求报头(header)
四、HTTP响应(Response)
1、状态码
2、响应报头(header)
3、响应正文(body)
五、总结
六、知识框架(思维导图)
HTTP协议是一种非常广泛的应用层协议。HTTP 往往是基于传输层的 TCP 协议实现的。(HTTP1.0 、HTTP1.1 、HTTP2.0 均基于TCP协议,HTTP3是基于UDP实现的,以下均用以TCP协议实现的HTTP协议来进行说明)
TCP/IP协议栈中,传输层协议是负责 端 到 端 之间的通信,而应用层协议负责说明传递的这个数据是干嘛的。
- 应用层:买的喷壶,这个喷壶是用来浇花?还是消毒?
- 传输层:我负责下单,商家负责发货,我们都只关心货到了没有。
应用层协议很多时候是有程序员自己定制的,根据实际的需求场景来设计协议。而HTTP协议就是一个写的很好的一个应用层协议。虽然是写好的,但是其自身的可扩展性还是很强的,可以让我们根据实际需要传输各种自定义的数据信息。
HTTP的具体应用场景很广泛,只要你打开浏览器,随便打开一个网站,这时候你就用到了HTTP。
一、HTTP协议工作过程
当我们在浏览器中输入一个 "网址", 此时浏览器就会给对应的服务器发送一个 HTTP 请求,对方服务器收到这个请求之后, 经过计算处理, 就会返回一个 HTTP 响应。
二、 协议格式
HTTP是一个文本格式的协议,即不需要理解具体的二进制位,更方便与人的肉眼观察。
而相比UDP、TCP、IP,这些协议都是属于“二进制”的协议,经常要理解到二进制的bit位。(UDP = 报头(源端口 ,目的端口,长度,校验和)+ 载荷)
对于HTTP的文本格式的协议,并不能直接看到,而是需要依靠抓包工具。借助一些 “抓包工具” 来获取到具体的HTTP交互过程中的请求和响应。
抓包工具:
其实就是一个第三方的程序。在这个网络通信的过程中,类似于 “代理”。
(可以想象为两个人吵架生气,但是又不得不说话的时候,就可以让第三个人来回递话。此时这个中间人就知道了他们两个的所有传递的对话了)
1、抓包工具Fiddler
Fiddler是一个专门抓HTTP的抓包工具,其安装直接在官网安装即可,注意在安装完之后要下载证书。
我们可以通过Fiddler来观察HTTP的协议格式了。
在上图的Fiddler界面中,左侧是一个列表,显示了当前抓到的所有的HTTP/HTTPS的数据报(HTTPS就只是在HTTP的基础山,引入了加密机制)。当双击选中左侧列表中的某个条目,并双击的时候,右侧就会显示这个条目的详细信息。上面是请求信息,下面是响应信息。
2、HTTP请求格式
请求分为 4 个部分:
(1)请求行(首行) 包含 3 个部分
(a)HTTP的方法,方法大概描述了这个请求想干啥。(GET的意思就是想从服务器获取到某个东西,后面会详细说明)。
(b)URL,描述了要访问的网络上的资源具体在哪。
(c)版本号,HTTP/1.1 表示当前使用的HTTP的版本时1.1 。(1.1 是当下最主流的版本,还可能是1.0 / 2 / 3)
(2)请求头(header) 包含了很多行
每一行都是一个键值对,键和值之间用 :空格 来分割。这里的键值对的的个数是不固定的(有可能多,有可能少),不同的键和值表示的含义也不同。
(3)空行 相当于请求头的结束标记
类似于链表的null。
(4)请求正文(body) 可选的,不一定有
3、HTTP响应格式
响应分为 4 个部分:
(1)首行 包含了 3 个部分
(a)版本号: HTTP/1.1
(b)状态码:200.... 描述了这个响应,是一个成功的还是失败的。以及不同的状态码描述了失败的原因。
(c)状态码的描述:OK...... 通过一个/一组简单的单词,来描述当前状态码的含义。(这里的OK顾名思义就是传输成功了)
(2)响应头(header)
也是键值对结构,每一个键值对占一行,每个键和值之间使用 : 空格 来分割。响应头中键值对的个数也是不确定的,不同的键值对表示不同的含义。
(3)空行
表示响应头的结束标记。
(4)响应正文(body)
服务器返回给客户端的具体数据。这里的东西可能有各种不同的格式(后面会详细说明),其中最常见的就是http格式。
注意:
上图中 body 部分出现了乱码的情况。原因:
乱码实质上是压缩之后的结果,因为一个服务器,最贵的硬件资源其实就是网络带宽。像这些HTTP响应,经常会比较大(因为要返回一个页面),所以就比较占用带宽。为了能够提高效率,服务器会经常返回 “压缩之后” 的数据,由浏览器收到之后再来解压。
4、HTTP协议格式总结
空行的作用:
因为在请求和响应中的报头部分,其内容里的键值对的数量是不固定的。而HTTP协议又是基于TCP协议来实现的,TCP协议是面向字节流的。因此这个空行就相当于 “报头的结束标记” 或者 “报头和正文之间的分隔符”,来解决 “粘包问题”。
三、HTTP请求(Request)
1、URL
URL的意思是统一资源定位符,即网络上唯一资源的地址符,既要明确主机是谁,又要明确主机上的那个资源。其实就是我们平常说的 “网址” 。(打开浏览器,打开网页的时候,地址栏里填写的这个网址就是URL)
(1)URL基本格式
① 协议方案名:描述了当前这个URL是给哪个协议来使用
- http:// 给HTTP使用
- https:// 给HTTPS使用
- jdbc:mysql:// 给jdbc.mysql使用
② 登录信息(认证):体现用户名密码,现在已经废弃不用了
③ 服务器地址:描述当前要访问的主机是什么
可以是一个IP地址,也可以是一个 域名。
域名会通过 DNS系统 解析成一个具体的 IP地址 。
④ 服务器端口号:表示当前要访问的主机上哪个应用程序
端口号大部分情况下是省略的。省略的时候并不是没有端口号,而是浏览器会自动赋予一个值。
- 对于 http 开头的URL,就会使用 80 端口作为默认值;
- 对于 https 开头的URL,就会使用 443 端口作为默认值。
⑤ 带层次的文件路径:文件路径,描述了当前要访问的服务器资源是啥
虽然请求的URL中,写的是一个文件路径。但是不一定服务器上就真存在一个对应的文件。这个文件可能是一个真实的在磁盘上存在的文件,也可能是虚拟的,由服务器代码构造出来的一个动态数据。
⑥ 查询字符串(query string):本质上是浏览器/客户端,给服务器传递的自定义的信息
相当于对获取都的资源提出了进一步的要求,查询字符串的内容,本质上也是键值对结构,键值对之间使用 & 分割,键和值之间使用 = 分割,查询字符串和前面路径之间用 ?分割。这里也是完全由程序员自己决定的。
⑦ 片段标识符:描述了要访问的当前html页面中哪个具体的子部分
能够控制浏览器滚动到相关位置。
(2)URL实例 (如何查看域名对应的IP地址)
https://blog.csdn.net/weixin_60358891/article/details/129912347?spm=1001.2014.3001.5502
例如上面的网址,就是一个URL。
注意:
域名是可以转成 IP地址的。使用ping命令就可以查看了。
在 cmd 中输入 ping xxxxxx ,即可看到域名解析的结果。
(3)URL encode / decode
当 query string 中如果包含了特殊字符,就需要对特殊字符进行转移,这个转义的过程就叫做 url encode ,反之,把转义后的内容还原回来,就叫做 url decode 。
/ : ? & = ...... 这些符号在URL中都是具有特定含义的,当我们的 query string 中也包含了这类的特殊符号,就可能导致URL被解析失败,因此我们就需要对 query string 中的这些符号进行转义。
例如:我们搜c++
此时可以发现,C++ 变成了 C%2B%2B 。
url encode 的规则:
把要转义的内容的 ASCII码值(二进制值)取出来,用十六进制表示,同时给每个要转义的字符加上% 。
2、方法
HTTP的方法有很多,但是最最最常用的还是 GET 和 POST 。
HTTP引入的这些方法,开始是表示了不同的语义的,但是随着时间的推移,大家写代码,基本都是使用 GET/POST这两个方法,不怎么考虑其本身的语义了。即 GET 也可以给服务器传输实体主体(给服务器送个东西),POST 也可以从服务器获取资源(从服务器上拿个东西)。
(1)GET 方法
使用 GET 方法请求的特点:
- 首行的第一部分为 GET
- URL 的 query string 可以为空,也可以不为空
- header 部分有若干个键值对结构
- body 部分为空
(2)POST 方法
使用 POST 方法请求的特点:
- 首行的第一部分为 POST
- URL 的 query string 一般为空(也可以不为空)
- header 部分有若干个键值对结构
- body 部分一般不为空,body 内的数据格式通过 header 中的 Content-Type 指定,body 的长度由 header 中的 Content-Length 指定。
3、GET 方法和 POST 方法的区别
GET 和 POST 没有本质上的区别。即GET能使用的场景,也能使用 POST,POST使用的场景,也能使用 GET 。
(1)语义上的区别
- GET 通常用来取数据
- POST通常用来上传数据
现状是,两个混着用了。
(2)习惯用法上的区别
通常情况下:
- GET 是没有 body 的,GET 通过 query string 向服务器传递数据;
- POST 是有 body 的,POST 通过 body 向服务器传递数据,但是 POST 没有 query string 。
如果我就想让 GET 有 body(自己构造一个带 body 的GET请求),或者让 POST 带有 query string ,也是可以的。
(3)等幂性上的区别
GET 请求一般是等幂的,POST 请求一般是不等幂的。
等幂:每次相同的输入,得到的输出结果是确定的。
不等幂:每次相同的输入,得到的输出结果是不确定的。
(4)是否能缓存上的区别
GET可以被缓存,POST不能被缓存。
承接等幂性上的区别。
GET是等幂性的,每次相同的输入,输出都一样,所以我们可以提前把结果记住,节省下次访问的开销。
POST是不等幂的,每次相同的输入,输出是不确定的,因此不能缓存。(没什么用)
3、请求报头(header)
(1)Host :表示服务器主机的地址和端口
(2)Content-Length:表示 body 中的数据长度
(3)Content-Type:表示 body 中的 数据的格式
常见选项:
- application/x-www-form-urlencoded:form 表单提交的数据格式。
- multipart/form-data:form 表单提交的数据格式。通常用于上传文件。
- application/json:数据为 json 格式。
(4)User-Agent(UA):表示浏览器/操作系统的属性
有这个的原因是,在早期时候,浏览器只能显示文本。但是随着时代的发展,浏览器可以显示更多样式,但这个过程中,有的人使用的浏览器还是只能显示文本的浏览器,因此就设计了在传输的过程中,标明操作系统的信息和浏览器的信息,然后根据这个来判断是发送哪类的数据。
(5)Referer:表示当前页面是从哪个页面跳转过来的。
Referer不一定有,如果是直接在浏览器地址栏输入地址,或者点击收藏夹进入页面时,是没有 Referer 的。
当我们打开百度搜索,通常前几个是广告,当我们点进去这个广告,一般都是会有 Referer 的。
(6)Cookie:浏览器给页面提供的一种能够持久化存储数据的机制
Cookie的具体组织形式:
- ① 先按照域名来组织,针对每个域名,分别分配一个小房间。
- ② 一个小房间里,又会按照 键值对的方式来组织数据。
最典型的,就是要存储用户当前的身份信息。当用户在登录页面完成身份认证后,此时服务器就会给浏览器返回一个用户的身份信息,浏览器就把这个信息保存到了一个特定的位置上,后序再访问同一个网站的其他页面的时候,浏览器再自动的带上这个身份信息,服务器就能识别了。(例如登录B站后,在首页面点击了一个视频,跳转到这个视频的页面里了,但是此时你的登录信息还是有的,所以可以直接三连,不需要再次登录)
也类似于就诊卡,你的基本信息都在医院的服务器上,你这个就诊卡只是存了你的ID,但是一刷就可以知道你的所有病情信息。这些关键信息在我们这里就称之为 “session” 对话 。服务器管理着很多会话,里面都存储了用户的关键信息(基本信息、要做的检查、病例...),每个 session 也有一个 sessionId(会话的标识),就诊卡上就存储的是这个会话的ID。
Cookie里存储的键值对,也是和 query string 类似,由程序员自己决定。
Cookie最重要的应用场景:
存储会话id,进一步的让访问服务器的后续页面的时候,能够带上这个个id,从而让服务器能够治党当前的用户信息。服务器上保存用户信息这样的机制就称为 Session 会话。
四、HTTP响应(Response)
1、状态码
状态码表示访问一个页面的结果。
- 2开头,成功 200
- 3开头,重定向 301 302
- 4开头,客户端出现错误 404 403
- 5开头,服务器出现错误 500 504
200 OK:访问成功
404 Not Found:没有找到资源
403 Forbidden:访问被拒绝(没有这个资源的访问权限)
405 Method Not Allowed :HTTP中的方法我们都可以使用,但是会出现对方的服务器不支持我们使用的方法的情况,就会出现这个状态码
500 Internal Server Error:服务器出现内部错误
504 Geteway Timeout: 服务器太繁忙了,导致出现超时的情况
302 Move temporarily:临时重定向(类似打电话的呼叫转移)在登录页面中经常会看见,用于实现登录成功后,自动跳转到哪个页面。
301 Moved Permanently:永久重定向
2、响应报头(header)
其中属性和请求报头中的属性大部分一致。
Content-Type:表示 body 中的 数据的格式
常见:
- text/html : body 数据格式是 HTML
- text/css : body 数据格式是 CSS
- application/javascript : body 数据格式是 JavaScript
- application/json : body 数据格式是 JSON
3、响应正文(body)
响应正文中的格式非常灵活,取决于响应报头中的 Content-Type。
- 1) text/html
- 2) text/css
- 3) application/javascript
- 4) application/json
五、总结
请求:
1.首行(方法,URL,版本号)
2.请求头(header),是若干个键值对,每个键值对占一行,键和值之间使用 冒号空格 来分割
3.空行,相当于请求头的结束标记
4.正文(body),里面的格式取决于请求头中的 Content-Type
(1)x-www-form-urlencoded 格式就和 query string 是一样的,也是键值对的结构,键值对之间使用 & 分割,键和值之间使用 = 分割,并且需要使用 urlencode
(2)form-data 上传文件
(3)json {}构成若干个键值对,键和值之间使用 : 分割,键值对之间使用 逗号 分割
响应:
1.首行(版本号,状态码,状态码描述)
2.响应头(header),也是若干个键值对,每个键值对占一行,键和值之间使用 冒号空格 来分割
3. 空行,也是响应头的结束标记
4.正文(body),里面的格式取决于响应头中的 Content-Type
(1)html
(2)css
(3)js
(4)json
URL的基本格式
方法的取值
状态码
请求头/响应头常见属性
六、知识框架(思维导图)