前言
大家好我是小帅,今天我们来了解应用层协议HTTP
文章目录
- [1. HTTP 请求响应格式(重点)](#1. HTTP 请求响应格式(重点))
-
- [1.1 HTTP 协议的⼯作过程](#1.1 HTTP 协议的⼯作过程)
- [1.2 HTTP请求格式](#1.2 HTTP请求格式)
- [1. 3HTTP响应格式](#1. 3HTTP响应格式)
- [2. HTTP 请求 (Request)](#2. HTTP 请求 (Request))
-
- [2.1 使⽤ ping 命令查看域名对应的 IP 地址](#2.1 使⽤ ping 命令查看域名对应的 IP 地址)
- [2.2 URL encode](#2.2 URL encode)
- [2.3 认识方法](#2.3 认识方法)
-
- [2.3.1 GET ⽅法](#2.3.1 GET ⽅法)
- [2.3.2 POST ⽅法](#2.3.2 POST ⽅法)
- [2.4认识请求 "报头" (header)](#2.4认识请求 "报头" (header))
- [2.5 认识请求 "正⽂" (body)](#2.5 认识请求 "正⽂" (body))
- [3. HTTP 响应(response)](#3. HTTP 响应(response))
-
- [3.1 认识 "状态码" (status code)](#3.1 认识 "状态码" (status code))
- [3.2 认识响应 "报头" (header)](#3.2 认识响应 "报头" (header))
1. HTTP 请求响应格式(重点)
HTTP (全称为 "超⽂本传输协议") 是⼀种应⽤⾮常⼴泛的 应⽤层协议.
在这里插入图片描述
HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议.
HTTP 往往是基于传输层的 TCP 协议实现的. (HTTP1.0, HTTP1.1, HTTP2.0 均为TCP, HTTP3 基于UDP 实现)
⽬前我们主要使⽤的还是 HTTP1.1 和 HTTP2.0 . 当前课堂上讨论的 HTTP 以 1.1 版本为主.
所谓 "超⽂本" 的含义, 就是传输的内容不仅仅是⽂本(⽐如 html, css 这个就是⽂本), 还可以是⼀些其他的资源, ⽐如图⽚, 视频, ⾳频等⼆进制的数据
1.1 HTTP 协议的⼯作过程
当我们在浏览器中输⼊⼀个 "⽹址", 此时浏览器就会给对应的服务器发送⼀个 HTTP 请求. 对⽅服务器收到这个请求之后, 经过计算处理, 就会返回⼀个 HTTP 响应.
事实上, 当我们访问⼀个⽹站的时候, 可能涉及不⽌⼀次的 HTTP 请求/响应 的交互过程.
HTTP 协议格式
HTTP 是⼀个⽂本格式的协议. 可以通过 Chrome 开发者⼯具或者 Fiddler 抓包, 分析 HTTP 请求/响应的细节.
- 左侧窗⼝显⽰了所有的 HTTP请求/响应, 可以选中某个请求查看详情.
- 右侧上⽅显⽰了 HTTP 请求的报⽂内容. (切换到 Raw 标签⻚可以看到详细的数据格式)
- 右侧下⽅显⽰了 HTTP 响应的报⽂内容. (切换到 Raw 标签⻚可以看到详细的数据格式)
- 请求和响应的详细数据, 可以通过右下⻆的 View in Notepad 通过记事本打开
我们后面会详细讲fidder的使用。
以下是⼀个 HTTP请求/响应 的抓包结果.
1.2 HTTP请求格式
-
⾸⾏: [⽅法] + [url] + [版本]
解释:
后面会讲更多的方法。
-
Header: 请求的属性, 冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束。
-
Body: 空⾏后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有⼀个Content-Length属性来标识Body的⻓度;
1. 3HTTP响应格式
案例:
-
⾸⾏: [版本号] + [状态码] + [状态码解释]
后面会讲解更多的状态码。
-
Header: 请求的属性, 冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束。
-
Body: 空⾏后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有⼀个Content-Length属性来标识Body的⻓度;== 如果服务器返回了⼀个html⻚⾯, 那么html⻚⾯内容就是在body中.==
协议格式总结
为什么 HTTP 报⽂中要存在 "空⾏"?
1 . 因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空⾏就相当于是 "报头的结束标记", 或者是"报头和正⽂之间的分隔符".
2 . HTTP 在传输层依赖 TCP 协议, TCP 是⾯向字节流的. 如果没有这个空⾏, 就会出现 "粘包问题".
2. HTTP 请求 (Request)
认识 URL
URL 基本格式
平时我们俗称的 "⽹址" 其实就是说的 URL (Uniform Resource Locator 统⼀资源定位符).
互联⽹上的每个⽂件都有⼀个唯⼀的URL,它包含的信息指出⽂件的位置以及浏览器应该怎么处理它.
URL 的详细规则由 因特⽹标准RFC1738 进⾏了约定:
⼀个具体的 URL:
https://v.bitedu.vip/personInf/student?userId=10000\&classId=100
可以看到, 在这个 URL 中有些信息被省略了
- 协议方案名
https : 协议⽅案名. 常⻅的有 http 和 https, 也有其他的类型. (例如访问 mysql 时⽤的jdbc:mysql )
- 登录信息
user:pass : 登陆信息. 现在的⽹站进⾏⾝份认证⼀般不再通过 URL 进⾏了. ⼀般都会省略
- 服务器地址
v.bitedu.vip : 服务器地址. 此处是⼀个 "域名", 域名会通过 DNS 系统解析成⼀个具体的 IP 地址. (通过 ping 命令可以看到源IP地址 )
- 端口号
端⼝号: 上⾯的 URL 中端⼝号被省略了. 当端⼝号省略的时候, 浏览器会根据协议类型⾃动决定使⽤哪个端⼝. 例如 http 协议默认使⽤ 80 端⼝, https 协议默认使⽤ 443 端⼝.
- 带层次的⽂件路径
/personInf/student就是一个文件路径
- 查询字符串(query string)
本质是⼀个键值对结构. 键值对之间使⽤ & 分隔. 键和值之间使⽤ = 分隔
query string 中的内容是键值对结构. 其中的 key 和 value 的取值和个数, 完全都是程序猿⾃⼰约定的. 我们可以通过这样的⽅式来⾃定制传输我们需要的信息给服务器.
- ⽚段标识
此 URL 中省略了⽚段标识. ⽚段标识主要⽤于⻚⾯内跳转. (例如 Vue 官⽅⽂:https://cn.vuejs.org/v2/guide/#起步, 通过不同的⽚段标识跳转到⽂档的不同章节)
2.1 使⽤ ping 命令查看域名对应的 IP 地址
- 在开始菜单中输⼊ cmd , 打开 命令提⽰符
- 在 cmd 中输⼊ ping www.baidu.com , 即可看到域名解析的结果.
2.2 URL encode
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现
⽐如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进⾏转义.
"+" 被转义成了 "%2B"
2.3 认识方法
2.3.1 GET ⽅法
GET 是最常⽤的 HTTP ⽅法. 常⽤于获取服务器上的某个资源.
在浏览器中直接输⼊ URL, 此时浏览器就会发送出⼀个 GET 请求.
另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求。
因为HTML里面连接了其他的连接,比如说前端三件套HTML,CSS,JavaScript.
使⽤ Fiddler 观察 GET 请求
打开 Fiddler, 访问 搜狗主⻚, 观察抓包结果.
- 是通过浏览器地址栏发送的 GET 请求。
- 下⾯的和 sogou 域名相关的请求, 有些是通过 html 中的 link/script/img 标签产⽣的, 例如
选中第⼀条
观察请求的详细结果:
java
GET https://www.sogou.com/ HTTP/1.1
Host: www.sogou.com
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://cn.bing.com/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: ABTEST=0|1729997827|v17; IPLOC=CN4401; SUID=4D8CE67859A5A20B00000000671DAC03; cuid=AAGM34WCTwAAAAuipcD0mAEANgg=; SUV=1729997829710527
GET 请求的特点
- ⾸⾏的第⼀部分为 GET
- URL 的 query string 可以为空, 也可以不为空
- header 部分有若⼲个键值对结构.
- body 部分为空.
关于 GET 请求的 URL ⻓度问题
HTTP 协议由 RFC 2616 标准定义, 标准原⽂中明确说明: "Hypertext Transfer Protocol -- HTTP/1.1,"
does not specify any requirement for URL length.
没有对 URL 的⻓度有任何的限制.
实际 URL 的⻓度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最⼤⻓度
是不同的, 但是现代浏览器⽀持的⻓度⼀般都很⻓; 在服务器端, ⼀般这个⻓度是可以配置的.
2.3.2 POST ⽅法
POST ⽅法也是⼀种常⻅的⽅法. 多⽤于提交⽤⼾输⼊的数据给服务器(例如登陆⻚⾯).
通过 HTML 中的 form 标签可以构造 POST 请求, 或者使⽤ JavaScript 的 ajax 也可以构造 POST 请求.
使⽤ Fiddler 观察 POST ⽅法
在登陆⻚⾯, 输⼊⽤⼾名, 密码, 验证码之后, 点击登陆, 就可以看到 POST 请求.
点击这个请求, 查看请求详情
POST https://edu.bitejiuyeke.com/auth/login HTTP/1.1
Host: edu.bitejiuyeke.com
Connection: keep-alive
Content-Length: 117
Access-Control-Allow-Origin: *
Accept: application/json, text/plain, /
Access-Control-Allow-Headers: Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x63090c11) XWEB/11275 Flue
Access-Control-Allow-Methods: PUT,POST,GET,DELETE,OPTIONS
Content-Type: application/json;charset=UTF-8
Origin: https://edu.bitejiuyeke.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://edu.bitejiuyeke.com/login
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: sidebarStatus=0
{"username":"asjkslasjak","password":"swPpcXg5PkeA1uL4wGdhkw==","uuid":"6c41dddca30f410abe41db69ade414f3","status":0}
POST 请求的特点:
- ⾸⾏的第⼀部分为 POST
- URL 的 query string ⼀般为空 (也可以不为空)
- header 部分有若⼲个键值对结构
- body 部分⼀般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的⻓度
由 header 中的 Content-Length 指定。
总结:
经典⾯试题: 谈谈 GET 和 POST 的区别:
-
语义不同: GET ⼀般⽤于获取数据(比如说:搜索请求获取一个界面), POST ⼀般⽤于提交数据(比如说:登录输入账号密码,获取主页界面).
-
GET 的 body ⼀般为空, 需要传递的数据通过 query string 传递, POST 的 query string ⼀般为空, 需
要传递的数据通过 body 传递
-
GET 请求⼀般是幂等的, POST 请求⼀般是不幂等的. (
如果多次请求得到的结果⼀样, 就视为请求是 幂等的
). -
GET 可以被缓存, POST 不能被缓存. (这⼀点也是承接幂等性)
其他的方法后面我们讲抓包工具在讲。
2.4认识请求 "报头" (header)
header 的整体的格式也是 "键值对" 结构.
每个键值对占⼀⾏. 键和值之间使⽤分号分割.
我们来了解里面的具体内容:
- Host
表⽰服务器主机的地址和端⼝.
- Content-Length
表⽰ body 中的数据⻓度.
- Content-Type
表⽰请求的 body 中的数据格式
- User-Agent (简称 UA)
包含:本机操作系统信息和浏览器信息
- Referer
表⽰这个⻚⾯是从哪个⻚⾯跳转过来的.
比如说:我从搜狗浏览器搜索bilbil到这个界面:
表⽰这个⻚⾯是从哪个⻚⾯跳转过来的. 还有登录进入界面时:
- Cookie
Cookie 中存储了⼀个字符串, 这个数据可能是客⼾端(⽹⻚)⾃⾏通过 JS 写⼊的, 也可能来⾃于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据)
往往可以通过这个字段实现 "⾝份标识" 的功能.
每个不同的域名下都可以有不同的 Cookie, 不同⽹站之间的 Cookie 并不冲突.
可以通过抓包观察⻚⾯登陆的过程:
1) 清除之前的 cookie
以码云为例
1)为了⽅便观察, 先清除掉之前登陆的 cookie
2)移除已经存在的 Cookie
登陆操作
请求:
响应:
可以看到, 响应中包含了 2个 Set-Cookie 属性.
其中我们重点关注第二个. ⾥⾯包含了⼀个 gitee-session-n 这样的属性, 属性值是⼀串很⻓的加密之后的信息. 这个信息就是⽤⼾当前登陆的⾝份标识. 也称为 "令牌(token)
3)关闭浏览器再次出现进入码云
第二进入不用输入账号密码,就是浏览器本地存储了
第二次不用账号密码进入码云响应:
没有了Set-Cookie因为第一次登录响应设置了,第二次登录时请求会把cookie值一起发送个服务器,从而快速找到客户端个人信息。
怎么理解这种机制?
可以这样理解
1)第一次把登录时,把账号密码给服务器,服务器存储这个客服端的个人信息,喜好(主页壁纸),服务器给客户端返回一个(set-cookei)类似于哈希值(也可以理解为令牌),用于下次登录发送请求时,给服务器发送这个值(令牌)服务器快速找到用户的信息(个性化,账号密码等),从而短时间不用登陆。
2.5 认识请求 "正⽂" (body)
正⽂中的内容格式和 header 中的 Content-Type 密切相关.
上面讲解登录码云就是这样的过程。
这里不多讲,多点去抓包。
3. HTTP 响应(response)
大概是这样的
3.1 认识 "状态码" (status code)
1)200 OK
这是⼀个最常⻅的状态码, 表⽰访问成功.
注意: 在抓包观察响应数据的时候, 可能会看到压缩之后的数据, 形如:
⽹络传输中 "带宽" 是⼀个稀缺资源, 为了传输效率更⾼往往会对数据进⾏压缩
2)404 Not Found
没有找到资源
浏览器输⼊⼀个 URL, ⽬的就是为了访问对⽅服务器上的⼀个资源. 如果这个 URL 标识的资源不存在,
那么就会出现 404
3)403 Forbidden
表⽰访问被拒绝. 有的⻚⾯通常需要⽤⼾具有⼀定的权限才能访问(登陆后才能访问). 如果⽤⼾没有登陆
直接访问, 就容易⻅到 403.
例如: 查看码云的私有仓库, 如果不登陆, 就会出现 403. 参考链接:https://gitee.com/HGtz2222/blog_python
4)302 Move temporarily
临时重定向
理解 "重定向"
就相当于⼿机号码中的 "呼叫转移" 功能.
⽐如我本来的⼿机号是 186-1234-5678, 后来换了个新号码 135-1234-5678, 那么不需要让我的朋友知
道新号码,只要我去办理⼀个呼叫转移业务, 其他⼈拨打 186-1234-5678 , 就会⾃动转移到 135-1234-5678 上.
在登陆⻚⾯中经常会⻅到 302. ⽤于实现登陆成功后⾃动跳转到主⻚.响应报⽂的 header 部分会包含⼀个 Location 字段, 表⽰要跳转到哪个⻚⾯.
案例:搜索不孕不育点击广告,服务器从百度跳转到广告主的服务器,这个就是重定向
5)500 Internal Server Error
服务器出现内部错误. ⼀般是服务器的代码执⾏过程中遇到了⼀些特殊情况(服务器异常崩溃)会产⽣这
个状态码.
咱们平时常⽤的⽹站很少会出现 500 (但是偶尔也能看到)
6)504 Gateway Timeout
当服务器负载⽐较⼤的时候, 服务器处理单条请求的时候消耗的时间就会很⻓, 就可能会导致出现超时
的情况.
这种情况在双⼗⼀等 "秒杀" 场景中容易出现, 平时不太容易⻅到.
总结:
3.2 认识响应 "报头" (header)
响应报头的基本格式和请求报头的格式基本⼀致.
类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义⼀致.
1)Content-Type
响应中的 Content-Type 常⻅取值有以下⼏种:
1. text/html : body 数据格式是 HTML
2. text/css : body 数据格式是 CSS
3. application/javascript : body 数据格式是 JavaScript
4. application/json : body 数据格式是 JSON
2)认识响应 "正⽂" (body)
正⽂的具体格式取决于 Content-Type. 这个前端会讲,我们把主要的列举出来。
- text/html
- text/css
- application/javascript
后面我们到服务器的时候会讲,请求的生成工具的使用。
好了,今天就到这里了。