系列文章目录
【网络通信基础】网络中的常见基本概念
【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序(万字博文)
【网络原理】UDP协议的报文结构 及 校验和字段的错误检测机制(CRC算法、MD5算法)
【网络原理】TCP协议的相关机制(确认应答、超时重传)
【网络原理】TCP协议的连接管理机制(三次握手和四次挥手)
【网络原理】IP协议的地址管理和路由选择
【网络原理】数据链路层 及 DNS域名系统
目录
系列文章目录
一、什么是 HTTP ?
二、HTTP 协议的基本格式
抓包工具 Fiddler 的使用
HTTP 请求
HTTP 响应
协议格式总结
三、认识 URL
URL encode
一、什么是 HTTP ?
整个网络原理中,按照TCP/IP五层模型,介绍了各个层次的核心协议。这里再重新谈谈应用层。
HTTP(超文本传输协议)是一种应用非常广泛的应用层协议.
HTTP 诞生于1991年。目前已经发展为最主流使用的一种应用层协议。
最新的 HTTP3 版本也正在完善中,目前 Google / Facebook 等公司的产品已经支持了。
HTTP往往是基于传输层的 TCP 协议实现的。(HTTP3之前,都是基于TCP实现的,HTTP3 基于UDP实现)
目前主要使用的还是 HTTP1.1 和 HTTP2.0。当前我们讨论的 HTTP 以 1.1 版本为主。
HTTP最主要的应用场景,就是网站,在浏览器和服务器之间传输数据。
当我们在浏览器中输入一个 搜狗搜索 的"网址"(URL) 时,浏览器就给搜狗的服务器发送了一个 HTTP 请求,搜狗的服务器返回了一个 HTTP 响应。HTTP协议的交互过程,是典型的一问一答模式。
这个响应结果被浏览器解析之后,就展示成我们看到的页面内容。(这个过程中浏览器可能会给服务器发送多个 HTTP 请求,服务器会对应返回多个响应,这些响应里就包含了页面 HTML,CSS,JavaScript,图片,字体等信息)
二、HTTP 协议的基本格式
前面说到,我们访问一个网站的时候,可能涉及不止一次的 HTTP 请求/响应 的交互过程。这些交互过程,可以通过 Fiddler 工具进行抓包。(wireshark 可以抓各种协议数据包,使用起来更复杂,fiddler 专注于 HTTP 的抓包)
此处只介绍基本格式,具体内容暂不详细介绍。
抓包工具 Fiddler 的使用
下载地址:https://www.telerik.com/fiddler
进入该网站后,首先选择经典版(免费)
第二步,填写信息,然后点击 Download
最后安装过程就是一路 next,安装完成后,就可以通过开始菜单打开 Fiddler 工具。
接下来要抓包,需要进行一个简单的设置:
点击OK之后,会弹出一个对话框,提示你“是否要安装证书”,必须要点“是”,否则就得卸载重装了。
Fiddler 相当于一个“代理”(类似于外卖小哥的角色)。
当浏览器访问 sogou.com 时,就会把 HTTP 请求先发给 Fiddler,Fiddler 再把请求转发给 sogou 的服务器。当 sogou 服务器返回数据时,Fiddler 拿到返回数据,再把数据交给浏览器。
因此,Fiddler 对于浏览器和 sogou 服务器之间交互的数据细节,都是非常清楚的。
如果上述的安装配置操作都完成,此时 Fiddler 就能抓到很多的数据包。这里的数据包只要系统上有任何一个程序(不一定是浏览器)使用了 HTTP/HTTPS,都能够被 Fiddler 给获取到。
- 左侧窗口显示了所有的 HTTP 请求/响应,可以选中某个请求查看详情。
- 右侧上方显示了 HTTP 请求的报文内容。(切换到 Raw 标签页可以看到详细的数据格式)
- 右侧下方显示了 HTTP 响应的报文内容。(切换到 Raw 标签页可以看到详细的数据格式)
- 请求和响应的详细数据,可以通过各位置右下角的 View in Notepad 通过记事本打开。
可以使用 ctrl + a 全选左侧的抓包结果,delete 清除所有被选中的结果。
HTTP 请求
一个 HTTP 请求,主要包含四个部分:
1. 首行:【方法】+【url】+【版本号】
2. 请求头(Header):请求的属性,各属性是由 “冒号 + 空格” 分割的键值对;每组属性之间使用\n分割;遇到空行Header部分结束。
3. 空行:请求头和消息主体之间由一个空行分隔。
4. 消息主体(Body):空行后面的内容都是Body。Body允许为空字符串。如果Body存在,则在Header中会有一个Content-Length属性来标识Body的长度。(有的HTTP请求有Body,有的没有)
该图中,除首行外,其余内容都是 请求头(Header),没有Body。
HTTP 响应
一个 HTTP 响应,也是包含四个部分:
1. 首行:【版本号】+【状态码】+【状态码解释】
2. 响应头(Header):请求的属性,各属性是由 “冒号 + 空格” 分割的键值对;每组属性之间使用\n分割;遇到空行表示Header部分结束。
3. 空行:响应头部和消息主体之间由一个空行分隔。
4. 消息主体(Body):空行后面的内容都是Body。Body允许为空字符串,如果Body存在,则在Header中会有一个Content-Length属性来标识Body的长度;如果服务器返回了一个html页面,那么html页面内容就是在Body中。
从该响应中,就能够清楚看到响应的四个主要部分了。
协议格式总结
HTTP报文中存在“空行”的原因:
- HTTP 协议并没有规定报头部分的键值对有多少个。空行相当于是“报头的结束标记”,或者说是“报头和正文之间的分隔符”。
- HTTP 在传输层依赖 TCP 协议,TCP是面向字节流的。如果没有这个空行标记,传输的时候就不知道哪里是报头,哪里是正文,就会出现“粘包问题”。
三、认识 URL
介绍完 HTTP 协议的基本格式后,再重点认识一下 URL。
URL(统一资源定位符,Uniform Resource Locator)是用于标识资源的位置和访问方式的地址。也就是平时我们俗称的“网址”.
URL 是一个非常重要的概念,早在 JDBC 的时候,就使用过 URL。
https://www.sogou.com 这就是一个最简单的 URL。
https:// 表示协议的名称;www.sogou.com 就是前面说过的域名。
一个完整 URL,结构还是比较复杂的:
- 服务器地址和端口号:此处使用域名表示,也可以使用IP地址(域名会通过DNS解析成具体的IP地址)。如果URL中不带端口号,浏览器就会自动给一个默认的端口(http-80;https-443)
- 带层次的文件路径:指定资源在服务器上的路径,表示要访问该位置的资源。
- 查询字符串(query string):以 ? 开头,包含由 & 分隔的键值对,键和值之间用 = 分隔。例如 ?name=zhangsan&age=20。键值对的取值和个数,完全由程序员自己约定,通过这样的方式,自己定制我们需要的信息传输给服务器。
- 片段标识符:主要用于页面内跳转。
URL中的可省略部分:
- 协议名:省略后默认为 http://
- ip地址/域名:在 HTML 中可以省略,省略后表示服务器的 ip/域名 与当前 HTML 所属的 ip/域名一致。
- 端口号:若省略,http 协议,端口号默认设为80;https 协议,端口号默认设为 443.
- 带层次的文件路径:省略后相当于 / 。有些服务器会在发现使用 / 路径的时候,自动访问 /index.html
- 查询字符串
- 片段标识
URL encode
在URL中,本身有些特殊字符具有特定的含义,例如:/ : ?@ 等,因此这些字符不能随意出现。
当某个参数需要带有这些特殊字符(如query string),就必须先对特殊字符进行转义。
对于汉字,也是要进行转义的。一个中文字符由 UTF-8 或者 GBK 这样的编码方式构成,虽然在 URL 中没有特殊含义,但是仍然需要进行转义。否则浏览器可能把汉字中某个字节当做 URL 中的特殊符号。
例如,在浏览器中搜索C++,查看此时的URL:
转义的规则如下:将需要转码的字符转为16进制,每2位做一位,前面加上%,编码成%XY格式。
对于 C++ 的 + 号进行转义,就是将 + 的 ASCII 码值拿出来,使用16进制表示,并且每2位前面加上%
再看看搜索蛋糕,URL对蛋糕进行转义的情况(需要复制出来,浏览器中的URL展示还是中文):
此处蛋糕的转义结果:%E8%9B%8B%E7%B3%95
URL decoding(URL解码)则就是URL encode的逆过程,用于将经过URL编码的字符串转换为原始的字符串形式。