协议
为了使数据在网络上从源头到达目的,网络通信的参与方必须遵循相同的规则,这套规则称为协议,它最终体现为在网络上传输的数据包的格式。
一、HTTP 协议介绍
- HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
- HTTP 是一种应用层协议,是基于 TCP/IP 通信协议来传递数据的,现主流使用 HTTP1.0 和 HTTP3.0
○ HTTP1.0、HTTP1.1、HTTP2.0 均为 TCP 实现
○ HTTP3.0 基于 UDP 实现。 - 支持 B/S 模式,支持基本认证和安全认证
- HTTP 允许传输任意类型的数据对象,正在传输的类型有 Content-Type 标记
- 可靠的无状态协议,无状态是指对事物没有记忆能力,这意味着如果后面的处理逻辑需要前面的状态只能重传信息( cookie 机制可以解决这个问题)。
二、作用和使用场景
当我们在浏览器输入一个网址,此时浏览器就会给对应的服务器发送一个 HTTP 请求,对应的服务器收到这个请求之后,经过计算处理,就会返回一个 HTTP 响应。并且当我们访问一个网站时,可能涉及不止一次的 HTTP 请求和响应的交互过程。
基础术语:
- 客户端 client: 主动发起网络请求的一端
- 服务器 server: 被动接收网络请求的一端
- 请求 request: 客户端给服务器发送的数据
- 响应 response: 服务器给客户端返回的数据
协议特点:一发一收
注意: 网络编程中,除了一发一收之外,还有其它的模式- 多发一收:例如上传大文件
- 一发多收:例如看直播时,搜索一个词条可以得到多个视频源
- 多发多收:例如串流(steam link、moonlight 等等)
三、HTTP 的工作流程
- 1、TCP 三次握手:client 和 server 建立 TCP 连接
- 2、client 向 server 发送 http 请求
- 3、server 接收 client 请求后响应,发送响应包(响应数据)给 client
- 4、TCP 四次挥手:client 和 server 断开 TCP 连接
HTTP 的流程
HTTP 长连接和短连接
- 长连接
○ 优点: 可以在一个 TCP 连接里面多次 HTTP 请求和响应交互,减少 tcp 建立连接的开销
○ 缺点:会存在队头阻塞的问题,会出现大量长连接占用问题(恶意创建众多 tcp 连接打满 server 的处理能力)
○ 队头阻塞问题在 HTTP2.0 之后解决
§ HTTP2.0 是多路复用且非有序阻塞的
§ HTTP2.0 提升了 TCP 连接的利用率 - 短连接
○ 不保持 TCP 连接,每次 HTTP 请求响应结束后就断开 TCP 连接,下次请求重建 TCP 连接
○ 不会造成队头阻塞的问题,但是交互频繁的时候互建立大量的 TCP 连接浪费资源
Http1.1 之后默认使用长连接
协议 | 开启 | 关闭 |
---|---|---|
HTTP1.0 | Connection: keep-alive | 默认 |
HTTP1.1 | 默认 | Connection: close |
- 如果服务端使用 nginx 做了反向代理,那么需要调整keepalive_timeout 参数
keepalive_timout 时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住 keepalive_timeout 秒后,才开始关闭这个连接。
TCP 的长连接
- 注意和 HTTP 的keep-alive 不同,TCP 有自己的keep-alive 叫做 TCP 保鲜机制
- net.ipv4.tcpkeepalivetime:表示TCP链接在多少秒之后没有数据报文传输启动探测报文
- net.ipv4.tcpkeepaliveintvl:前一个探测报文和后一个探测报文之间的时间间隔
- net.ipv4.tcpkeepaliveprobes:探测的次数
- 逻辑为:tcpkeepalivetime 时间没有数据则开始探测,每过tcpkeepaliveintvl探测一次,最多探测tcpkeepaliveprobes次,如果全部失败则关闭TCP连接。
四、数据包格式
burp 抓包
POST /api/v2/filereputation/query HTTP/1.1
Host: 10.252.177.58
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: /
Connection: close
Content-Type: application/json
Content-Length: 62
{“param”: “9e3bcd91672cb3e4d2e9345b71bf50ff”, “apikey”: “123”}
URL 的完整格式
协议类型:[//[访问资源需要的凭证信息@]服务器地址[:端口号]][/资源层级 UNIX 文件路径]文件名[?查询字符串][#片段标识符]
HTTP 的请求方法
1、GET 方法
- GET 是最常用的 HTTP 方法,常用于获取服务器上的某个资源。以下几种方式都会触发 GET 方法的请求
○ 在浏览器中直接输入 URL 回车或点击浏览器收藏夹中的链接,此时浏览器就会发送出一个 GET 请求。HTML 中的 link、img、script 等标签的属性中放的 URL,浏览器也会构造出 HTTP GET 请求
○ 使用 Javascript 重点 ajax,也能构造出 HTTP GET 请求,各种编程语言(只要能够访问网络),就都能够构造出 HTTP GET 请求
- GET 请求的特点:
○ 首行里面的第一个部分就是 GET
○ URL 里面的 query string 可以为空,也可以不为空【Params 一般专指 Query 参数】
○ GET 请求的 header 有若干个键值对结构
○ GET 请求的 body 一般是空的
2、POST 方法
- POST 方法也是一种常见的方法,多用于提交用户输入的数据给服务器(如登录页面)。以下几种方法都会触发 POST 方法的请求
○ 通过 HTML 中的 form 标签可以构造 POST 请求
○ 使用 JavaScript 的 ajax 可以构造 POST 请求
- POST 请求的特点:
○ 首行第一个部分就是 POST
○ URL 里面的 query string 一般是空的
○ POST 请求的 header 里面有若干个键值对
○ POST 请求的 body 一般不为空(body 的具体数据格式,由 header 中的 Content-Type 来描述;body 的具体数据长度,由 header 中的 Content-Length 来描述
3、GET 和 POST 的区别
- GET 和 POST 其实没有本质区别,使用 GET 的场景完全可以使用 POST 代替,使用 POST 的场景一样可以使用 GET 代替。但是在具体的使用上,还是存在一些细节的区别
- GET 习惯上会把客户端的数据通过 query string 来传输(body 部分是空的)
- POST 习惯上会把客户端的数据通过 body 来传输(query string 部分是空的)
- GET 习惯上用于从服务器获取数据,POST 习惯上是客户端给服务器提交数据
- 一般情况,程序员会把 GET 请求的处理,实现成“幂等”的,对于 POST 请求的处理,不要求实现成“幂等”【幂等:指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的】
- GET 请求可以被缓存,可以被浏览器保存到收藏夹中,POST 请求不能被缓存
五、wireshark抓包分析
暂无
六、几种常用的 header
header 的整体格式是键值对结构,每个键值对占一行,键和值之间使用 冒号+空格 进行分割
以下介绍几个常见的报头
- Host
○ HOST 的值表示服务器主机的地址和端口(地址可以是域名,也可以是 IP;端口号可以省略或者手动指定) - Content-Length
○ Content-Length 表示 body 的数据长度,长度单位是字节 - Content-Type
○ Content-Type 表示 body 的数据格式,以下介绍三种请求中的数据格式
§ application/x-www-form-urlencoded
这是 form 表单提交的数据格式,此时 body 的格式就类似于 query string(是键值对的结构,键值对之间使用 & 分割,键与值之间使用 = 分割
§ multipart/form-data
这是 form 表单提交的数据格式(需要在 from 标签上加上 enctyped=“multipart/form-data”),通常用于 HTML 提交图片或者文件
§ application/json
此时 body 数据为 json 格式,json 格式就是源自 js 的对象的格式。用一个 { } 括住,里面有多个键值对,键值对之间使用逗号分割,键和值之间使用冒号分割 - User-Agent(简称 UA)
UA 在早年是一个非常有用的字段,网站的开发者可以根据它来检测页面的“兼容性”
○ User-Agent 表示浏览器或者操作系统的属性,形如:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/91.0.4472.77 Safari/537.36
○ Windows NT 10.0; Win64; x64 表示操作系统信息
○ AppleWebKit/537.36 (KHTML, like Gecko)Chrome/91.0.4472.77 Safari/537.36 表示浏览器信息 - Referer
Referer 表示这个页面是从哪个页面跳转过来的,这是一个很有用的字段
注意: 如果直接在浏览器中输入 URL 或直接通过收藏夹访问页面时,是没有 Referer 的 - Cookie
○ Cookie 是什么?
Cookie 是浏览器提供的一种让程序员在本地存储数据的能力
○ 为什么需要 Cookie?
如果没有 Cookie,直接将要存储的数据保存在客户端浏览器所在的主机的硬盘上,那么就会出现很大的安全风险,比如当你不小心打开某个不安全的网站,该网站就可以在你的硬盘上写一个病毒程序,那么你的电脑就挂了!因此浏览器为了保证安全性,就禁止网页中的代码访问主机的硬盘(无法在 JS 中读写文件),因此也就失去了持久化存储的能力,故 Cookie 就很重要!
○ Cookie 里面存的是什么?
Cookie 中存储了一个字符串,是键值对结构的,键值对之间使用 ;分割,键和值之间使用 = 分割
○ Cookie 来自哪里,如何往 Cookie 中存储数据?
Cookie 这个数据可能是客户端(网页)自行通过 JS 写入的,也可能来自于服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据。
Cookie 在浏览器这边是按照域名维度来存储的,例如我们打开 CSDN 的首页,点击网址栏左边的一把小锁就能找到 Cookie,我们就可以看到打开这个网页时,系统按照不同域名设置了 Cookie
○ Cookie 要到哪里去?
Cookie 字段会在后续的请求中,把浏览器本地存储的这些键值对再发送回服务器
○ Cookie 的应用
Cookie 的一个经典应用就是保持客户端的登录状态
○ Cookie 的缺陷:
每次请求都要把该域名下所有的 Cookie 通过 HTTP 请求传给服务器,因此 Cookie 的存储容量是有限的