目 录
HTTP 协议
HTTP 是什么
HTTP (全称为 “超文本传输协议”) 是一种应用非常广泛的 应用层协议(当前最广泛使用的协议)
互联网世界,数据传输,需要“协议"
协议拆分 又叫做 协议分层
HTTP 往往是基于传输层的 TCP 协议实现的. (HTTP1.0, HTTP1.1, HTTP2.0 均为TCP, HTTP3 基于 UDP 实现)
目前我们主要使用的还是 HTTP1.1 和 HTTP2.0 . 当前讨论的 HTTP 以 1.1 版本为主.
理解 HTTP 协议的工作过程
当我们在浏览器中输入一个 搜狗搜索的 “网址” (URL) 时, 浏览器就给搜狗的服务器发送了一个 HTTP 请求, 搜狗的服务器返回了一个 HTTP 响应.
这个响应结果被浏览器解析之后, 就展示成我们看到的页面内容. (这个过程中浏览器可能会给服务器发送多个 HTTP 请求, 服务器会对应返回多个响应, 这些响应里就包含了页面 HTML, CSS, JavaScript, 图片, 字体等信息).
所谓 “超文本” 的含义, 就是传输的内容不仅仅是文本(比如 html, css 这个就是文本), 还可以是一些其他的资源, 比如图片, 视频, 音频等二进制的数据.
事实上, 当我们访问一个网站的时候, 可能涉及不止一次的 HTTP 请求/响应 的交互过程.
可以通过 chrome 的开发者工具观察到这个详细的过程.
通过 F12 打开 chrome 的开发者工具, 切换到 Network 标签页. 然后刷新页面即可看到如下图效果. 每一条记录都是一次 HTTP 请求/响应
但是此处的抓包工具不是很方便,功能也有限,于是以 Fiddler 为例,这就是一个更好的抓包工具(下载链接点击此处)(https://www.telerik.com/fiddler)(安装过程比较简单, 一路 next 即可.)
注意:
- 此处我们下载的是 Fiddler Classic 经典版的
安装完成之后在菜单里找到 Fiddler 打开即可
左侧是一个 http 的请求列表,抓到了哪些请求。双击左侧列表中的某个请求,此时就会在右侧显示详细情况。
Fiddler 相当于一个 “代理”。在电脑中的其他的 代理程序/浏览器插件,很容易和 fiddler 冲突的!!只需要关闭其他程序即可。
HTTP是格式上非常有特点的协议.
fiddler 为了方便我们来查看内容,就对这里的数据做了一些格式化整理,因此初学阶段还是先看原始的,没有整理过格式的内容。
点击这个按钮,可以使用记事本打开文件.
- TCP,UDP,IP这些都是属于"二进制协议"协议中的数据,是以二进制的方式来组织的.如果拿记事本打开之后,里面是一堆乱码.
- HTTP则是一个"文本协议",协议中的数据,是以文本的方式来组织的.拿记事本打开之后,里面不是乱码~~
在响应文本里可能会乱码,网络上传输的数据也可以进行压缩,对于HTTP来说,请求数据一般比较简短,就不必压缩,响应数据可能会比较长!!通过压缩,就可以节省传输的带宽!!
压缩非常常见,fiddler内置了解压缩功能
经过解压缩(decode)之后,响应的内容变回了文本,同时仔细观察可以看到当前这个响应的内容正是一个HTML。
抓包结果
HTTP请求
- 首行,请求的第一行
- GEN:HTTP 的方法
- https://www.sogou.com/:HTTP 要请求的资源
- HTTP/1.1:版本号
- 请求报头header
header 里面都是"键值对",此处的键和值都是有固定含义的。
-
空行,是请求报头(header)的结束标记,报头里有多少个键值对(有多少行?)不确定的,遇到空行就认为是结束了。
-
正文(body),不是所有的HTTP请求都有正文.
只要fiddler开启状态,此时就会"持续抓包"
咱的电脑上总会有程序在后台偷偷的通过HTTP和服务器进行交互
因此为了防止混淆,就可以把fiddler 原来已经抓到的包,清空一下,再抓新的
- 1.随便点一个
- 2.ctrl + a全选
- 3.delete清空
HTTP响应
- 首行
- HTTP/1.1:版本号
- 200:状态码
- ok:状态码的描述
- 响应报头(header)
同样也是键值对的结构,每一行是一个键值对。每个键和值之间使用冒号空格来分割
-
空行.作为响应报头的结束标记
-
响应正文body
这里也可能是CSS或者JS或者图片等
协议格式总结:
为什么 HTTP 报文中要存在 “空行”?
因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 “报头的结束标记”, 或者是 “报头和正文之间的分隔符”.
HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 “粘包问题”.
HTTP 请求 (Request)
认识 URL
URL 基本格式
URL 的详细规则由 因特网标准RFC1738 进行了约定.点击此处跳转(https://datatracker.ietf.org/doc/html/rfc1738)
URL:唯一资源定位符,描述了互联网上的唯一的一个资源.(平时俗称的网址)
服务器地址,你的服务器在哪里呢,你的服务器的IP地址是啥
当然,上面的URL里面,地址并不是一个原始的IP地址,而是一个域名
DNS会把域名给解析成IP地址
明确了IPР地址,可以找到对应的服务器了!!
但是还需要知道地址上对应的应用程序是啥,就通过端口号来做区分,端口号是一个必须的信息 ! ! URL里面如果没写端口,此时浏览器就会给一个默认值。
如果是http://默认端口是80,如果是 https://默认端口是443。如果服务器部署在其他的端口上,此处URL里写的端口号也就得随之改变了
通过IP确定了主机
通过端口号确定了应用程序
一个应用程序下,可能管理着很多的资源.(像搜狗来说,上面就包含了很多的html页面)
一次请求,只是访问一个具体的资源.这次请求是访问哪个呢?这个就需要通过"带层次结构的路径"来进行确定
查询字符串:query string
请求中可以带上的一些"参数"
你去楼下餐馆吃饭,老板,来个麻辣烫!!! 老板问:你是麻辣/微辣/特辣 ? 我要个不辣的
吃饭://楼下餐馆:餐馆老板/麻辣烫?口味=不辣&是否要放香菜=放&是否要放葱=放
查询字符串,请求发给服务器的时候带上的参数
- ? 作为查询字符串的起始标志
- ? 后面的内容就是查询字符串的本体了.
- 通过键值对的方式来组织的
- 键值对之间使用 & 来分割.
- 键和值之间使用 = 来分割.
键值对的含义我们是不知道的,只有设置它的内部人员才知道
综上:
一个具体的 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 命令可以看到, v.bitedu.vip 的真实 IP 地址为 118.24.113.28 )
- 端口号: 上面的 URL 中端口号被省略了. 当端口号省略的时候, 浏览器会根据协议类型自动决定使用哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.
- /personInf/student : 带层次的文件路径.
- userId=10000&classId=100 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使用 & 分隔. 键和值之间使用 = 分隔.
- 片段标识: 此 URL 中省略了片段标识. 片段标识主要用于页面内跳转. (例如 Vue 官方文档: https://cn.vuejs.org/v2/guide/#%E8%B5%B7%E6%AD%A5, 通过不同的片段标识跳转到文档的不同章节)
关于 URL encode
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
此时就需要把这些特殊符号进行"转码”,就叫做urlencode
转义的规则如下: 将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式
链接:https://tool.chinaz.com/Tools/urlencode.aspx 点击此处直接跳转
认识 “方法” (method)
实际开发中 GET 占八成,POST 占一成,其余的合起来占一成。
- GET
GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源(这是这个方法原始的语义,但是实际使用的时候,也不一定完全遵守,完全也可以使用GET让服务器新增一个数据/删除一个数据/修改一个数据…)
哪些场景触发一个GET请求呢?
1.浏览器地址栏输入一个URL,直接回车点收藏夹里的收藏的网址.
2.很多的HTML标签, a, img, link, script 也会产生GET请求.
3.form
4.ajax
GET的典型特点:
1.URL的query string有时候有,有时候没有
2. body通常是空
关于 GET 请求的 URL 长度问题
网上有些资料上描述: get请求长度最多1024kb 这样的说法是错误的.
HTTP 协议由 RFC 2616 标准定义, 标准原文中明确说明: “Hypertext Transfer Protocol –
HTTP/1.1,” does not specify any requirement for URL length.
没有对 URL 的长度有任何的限制.
实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最大长
度是不同的, 但是现代浏览器支持的长度一般都很长; 在服务器端, 一般这个长度是可以配置的.
POST请求:
把信息上传/提交给服务器.(也是POST的初心,但是实际开发的时候也不一定遵守完全可以使用post来获取/删除/修改)
1.登录
2.上传文件
POST的特点:
1.首行的一个部分是POST
2.URL里通常没有query string
3.通常有body
浏览器和服务器交互的时候,总是需要提交一些数据给服务器的,这里情况在提交的过程中,相关的信息,可以放到query string里,也可以放到body 中。
query string是固定的键值对格式
body中则是可以使用更多的格式来组织
常见的面试题:
GET和POST之间的区别?
这俩方法没有本质区别!!!彼此之间不能相互替代,但是GET和POST之间则是可以相互替代的。
没有本质区别,不代表 " 没有区别 " 使用习惯上还是存在区别的
1.GET 主要使用用来获取数据. POST 主要使用给服务器提交数据~(虽然不必强制遵守,但是习惯上大部分情况下还是会遵守的)
2.GET 主要通过 query string 来传递数据, POST 则是使用 body 传递数据.(也不是强制遵守的.也是习惯用法)
3.GET 请求一般建议,是实现成 “幂等的”,POST则不要求"幂等"(如果多次输入的内容相同,多次得到的结果也完全相同,称为“幂等")
4.GET 一般是可以被缓存的/可以放到收藏夹中的,POST一般不要求被缓存/不能放入收藏夹(不绝对,可以省略)
认识请求 “报头”(header)
1. Host
访问的服务器的主机/地址是啥
2. Content-Length 和 Content-Type(搭配body 使用的)
Content-Length:表示 body 中的数据长度.
Content-Type:表示请求的 body 中的数据格式.
由于 HTTP 是基于 TCP 的,在学 TCP 的时候,TCP是一个面向字节流的协议,基于TCP的应用层协议,务必要明确数据报和数据报之间的边界,否则就会出现粘包问题。于是就要指定长度和指定分隔符了。
HTTP请求的body的数据格式常见的就几个
1.json
2.urlencoded(全称 application/x-www-form-urlencoded)
格式就和 query string 是一样的,键值对,键值对之间使用&分割,键和值之间使用=分割。就相当于是把query string拿到了body 中。
3.form-data(上传文件的时候会涉及到)
在HTTP响应中,还有一些其他的Content-Type
3. User-Agent (简称 UA)
表示浏览器/操作系统的属性
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 表示浏览器信息.
User-Aaent就描述了你在啥样的设备上网!!
现在 UA 起到的作用,主要是区分,请求是来自于PC还是移动端.(操作系统)
4. Referer
表示这个页面是从哪个页面跳转过来的(Referer 不一定100%有的,如果直接从浏览器地址栏输入/点收藏夹,不会有referer)
5. Cookie
Cookie是浏览器在本地存储数据的一种机制
浏览器为了保证用户的安全,浏览器针对页面上运行的代码,做出了很多的限制最典型的,就是禁止浏览器页面代码,访问本地磁盘,浏览器不让你访问磁盘,你要想持久化的在浏览器这边保存一些信息,又得访问磁盘。于是浏览器不是完全给你限制死,不是一点都不能使用磁盘,可以在限定条件下,能够使用一点点(不能访问到磁盘的其他文件),同时页面代码,也别任意存数据,只能存简单键值对
点击这个小锁头图标,就能看到当前页面的 cookie
浏览器为了进一步的保证安全, cookie都是分别存的.每个网站(每个域名)有一组自己的cookie,彼此之间不干扰
总结 cookie:
- cookie 是啥? 浏览器允许页面在本地持久化存储数据的一种机制
- cookie 的内容从哪里来呢? 是从服务器来的,网站上面主要的数据存储仍然是在服务器上的,数据也就是从服务器写回给浏览器的。
- cookie 的内容到哪里去呢? 再传回给服务器,例如网站通过登录之后,明确了用户的身份信息,就把身份标识返回给了浏览器,浏览器下次访问服务器,就会带着身份标识,服务器就可以认出用户是谁了。
- cookie 这里的键值对内容是啥含义? 也是自定义的!!只有实现这里功能的程序猿才知道
认识请求 “正文” (body)
依旧是:Content-Type,Content-Length。
HTTP 响应
响应中的大部分内容,都是和请求类似的
认识 “状态码” (status code)
HTTP/1.1 200 OK
200 OK 为常见的状态码,表示访问成功。
- 200 表示成功了~~(没出错)
- 404 表示"Not Found”要访问的资源没找到!!
- 403 表示"访问被拒绝"你访问的资源存在,但是没权限
- 405 表示请求的方法不支持,你使用 DELETE 方法来访问,人家服务器不支持 DELETE
- 500 服务器内部错误(服务器挂了,出异常…)
- 504 超时,请求发过去之后,迟迟没收到回应,浏览器等待的时间到了,就超时了
- 302/301 都是重定向
重定向例子:我有一个手机号码,我想换一个手机号码,我的朋友同学亲人都是存的旧的号码,我想让他们都重新存新号码,就比较麻烦,因此直接去运营商搞个呼叫转移的业务,如果有人打旧的号码,自动转接到新号码上。
状态码小结:
认识响应 “报头” (header)
响应报头的基本格式和请求报头的格式基本一致.
类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义一致.(取值差别大)
Content-Type
响应中的 Content-Type 常见取值有以下几种:
- text/html : body 数据格式是 HTML
- text/css : body 数据格式是 CSS
- application/javascript : body 数据格式是 JavaScript
- application/json : body 数据格式是 JSON
认识响应 “正文” (body)
正文的具体格式取决于 Content-Type. 观察上面几个抓包结果中的响应部分
Content-Type: text/html; charset=utf-8
有时候写代码的时候需要考虑手动指定字符编码,保证返回的内容不是乱码。
以上内容都是 HTTP 协议报文格式
如何通过代码构造 HTTP 请求?
最基础的操作,就是直接在浏览器地址栏输入,构造出GET请求。
使用代码构造,主要是两种方式.
- 基于form标签
- 基于ajax
通过 form 表单构造 HTTP 请求
action:表示要访问的资源是啥
method:构造的请求方法是啥
username:键值对的键
form提交的数据,是键值对的结构。当我们提交form表单的时候,就会构造出形如 username=asdfasdfasdf 这样的键值对数据,通过 query string 或者 body 传给服务器了。但是此时虽然把 form 和 input 都准备好,但是还缺少一个能让咱们提交出请求的一个开关。
这是一个 " 发送按钮 " ,真正点击这个按钮的时候,浏览器才会真的构造出HTTP请求,并发送给服务器。
点击之后就会发生跳转
在 fiddler 里面抓包
username=abc 就是 input 标签里对应的键值对
一个 form 表单里可以有多组这样的键值对
username=abc&password=123 这就是两组键值对了
abc 和 123 是我们输入框自己输入的内容
form 只支持 GET 和 POST ,其他的方法都不支持了
当使用GET的方式提交的时候,用户名和密码就显示到浏览器地址栏中了!!!
之所以一般登录都是基于 POST 实现,原因就是基于 GET 的话,会把用户名和密码直接显示到地址栏上,容易被别人一眼就瞄走了
既然如此,是否可以说,POST 比 GET 更安全呢 ? 不成立的!!
保证安全的关键,是针对密码进行加密,而不是放到 body 里不能直接看到就算安全,放到 body 中,如果不加密的话,虽然浏览器不能直接显示,但是随便一抓包,就抓出来了
form 效果就是构造 HTTP 请求.
action 描述了 HTTP 请求 UR L的地址/端口/路径
method 描述了HTTP请求的方法.
搭配一些input标签,就可以构造出一些键值对数据.
这些键值对根据方法是 GET 还是 POST ,来分别通过 URL 的 query string 还是 body 来进行传输
通过 ajax 构造 HTTP 请求
从前端角度, 除了浏览器地址栏能构造 GET 请求, form 表单能构造 GET 和 POST 之外, 还可以通过 ajax 的方式来构造 HTTP 请求. 并且功能更强大.(是浏览器和服务器之间异步交互数据的方式)
ajax 全称 Asynchronous(异步) Javascript And XML
这里的描述的是进行 IO 操作的时候,结果是发送方自己来主动获取,还是接收方把结果推送回发送方。
客户端自己主动获取结果 --> 同步
客户端等着服务器把数据推送过来 --> 异步
ajax 能够传输的数据不仅仅是 XML 也可以是其他任何格式的数据
ajax 是浏览器给 JS 提供的一个和服务器交互数据的机制浏览器就提供了一组原生的API ,XMLHttpRequest(用起来不方便)
很多 js 的第三方库,就针对 ajax 进行了封装最典型的就是 jQuery
在浏览器中搜 jQuery cdn 然后找到如下:
点击进去之后
复制这个路径,到浏览器中可以查看
也可以放到代码里
存放 jQuery 的两个方法:
1.直接引入网络路径
服务器挂了就用不了了,但是 jQuery 比较稳定,一般不会挂掉。人在国内访问国外的时候可能访问不到。
2.把 jQuery 文件内容拷贝到本地
在本地创建一个 jquery.min.js 文件(文件名可以随便起)
把页面打开的 jquery 的内容全选(ctrl+a)复制粘贴过来~~(保证你的复制粘贴是正确)
粘贴过来只有两行,实际上只有两行。
以上 jQuery 就准备好了,接下来使用 jQuery 构造请求
红色区域是我们自己写的代码,要保证先加载 jQuery 才能编写 jQuery 相关的代码
jQuery 构造 ajax 请求的核心函数.
$是一个变量名,是 jquery 中的一个特殊对象
jquery 里面提供的各种 API,都是以 $对象 的方法的方式来体现的
回调函数,就是现在不着急执行,而是等满足一定的条件/时机的时候,再进行执行
这个代码,已经完成了 ajax 程序的编写了但是如果直接执行,还会出现问题!!!
这个报错,是 ajax 中的一个典型的问题,“跨域” 问题(当前的 HTML 所对应的 “域名”,是一个本地路径。ajax 访问的请求,是百度的服务器)
浏览器为了保证网络安全,禁止 ajax 的跨域访问。跨域操作也不是100%禁止的,要想允许跨域访问,就需要百度的服务器支持,但是百度自然不会允许咱们跨域访问的,后面可以自己搭建一个自己的服务器,自己服务器的页面自然可以 ajax 访问自己的服务器了。
HTTPS
HTTPS 是什么
HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层.
HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现一些被篡改的情况.
臭名昭著的 “运营商劫持”
不止运营商可以劫持, 其他的 黑客 也可以用类似的手段进行劫持, 来窃取用户隐私信息, 或者篡改内容.
HTTPS 就是在 HTTP 的基础上进行了加密,进一步的来保证用户的信息安全
“加密” 是什么
加密就是把 明文 (要传输的信息)进行一系列变换, 生成 密文 .
解密就是把 密文 再进行一系列变换, 还原成 明文 .
在这个加密和解密的过程中, 往往需要一个或者多个中间的数据, 辅助进行这个过程, 这样的数据称为 密钥 (正确发音 yue 四声, 不过大家平时都读作 yao 四声)
HTTPS 的加密过程
引入对称加密
对称加密其实就是通过同一个 “密钥” , 把明文加密成密文, 并且也能把密文解密成明文
由于数据是加密的,黑客并不知道,明文是什么。前提是黑客不知道密钥是啥!!!如果知道了,还是能破解的!!!
客户端和服务器使用的密钥,是一个啥样的密钥??
服务器不只是和一个客户端交互,同时和一堆客户端交互的,针对这么多的客户端,使用的是相同的密钥,还是不同的呢?
如果是相同的,黑客只要伪装自己是一个客户端就拿到这个密钥了!!!
每个客户端,在和服务器连接上的时候,自己生成一个密钥!!每个客户端生成的密钥都不相同。
如何把客户端生成的密钥,传递给服务器呢 ? ? 如果直接明文传输密钥,密钥就可能被黑客给获取到
引入非对称加密
非对称加密要用到两个密钥, 一个叫做 “公钥”, 一个叫做 “私钥”.
公钥和私钥是配对的. 最大的缺点就是运算速度非常慢,比对称加密要慢很多.
- 通过公钥对明文加密, 变成密文
- 通过私钥对密文解密, 变成明文
也可以反着用
- 通过私钥对明文加密, 变成密文
- 通过公钥对密文解密, 变成明文
非对称加密的数学原理比较复杂, 涉及到一些 数论 相关的知识. 这里举一个简单的生活上的例子.
A 要给 B 一些重要的文件, 但是 B 可能不在. 于是 A 和 B 提前做出约定:
B 说: 我桌子上有个盒子, 然后我给你一把锁, 你把文件放盒子里用锁锁上, 然后我回头拿着钥匙来开锁取文件.
在这个场景中, 这把锁就相当于公钥, 钥匙就是私钥. 公钥给谁都行(不怕泄露), 但是私钥只有 B 自己持有. 持有私钥的人才能解密
- 服务器生成一对公钥和私钥,自己保留私钥,公钥公开出去,客户端就可以拿到公钥了!!
- 客户端在本地生成对称密钥, 通过公钥加密, 发送给服务器.
- 由于中间的网络设备没有私钥, 即使截获了数据, 也无法还原出内部的原文, 也就无法获取到对称密钥
- 服务器通过私钥解密, 还原出客户端发送的对称密钥. 并且使用这个对称密钥加密给客户端返回的响应数据.
- 后续客户端和服务器的通信都只用对称加密即可. 由于该密钥只有客户端和服务器两个主机知道, 其他主机/设备不知道密钥即使截获数据也没有意义.
既然非对称加密这么香,为啥还要用对称加密呢 ?
非对称加密的加密和解密的开销,都是非常大的就不如对称加密轻量,为了让安全和效率同时都具备
上述的过程并非无懈可击,还有中间人攻击!!
例如 A 和 B 非法交易,然后有一个警察充当了中间人,在和 A 交易的时候,警察当 B ,在和 B 交易的时候充当 A 。这就有足够的证据抓住这两个人。
如何解决中间人攻击的问题呢?破解中间人攻击的关键,就是得让客户端能够验证,当前这里的公钥是否是来自于真实的服务器!!!
引入证书
在客户端和服务器刚一建立连接的时候, 服务器给客户端返回一个 证书.
这个证书包含了刚才的公钥, 也包含了网站的身份信息.
这个证书就好比人的身份证, 作为这个网站的身份标识. 搭建一个 HTTPS 网站要在CA机构先申请一个证书. (类似于去公安局办个身份证).
这个 证书 可以理解成是一个结构化的字符串, 里面包含了以下信息:
- 证书发布机构
- 证书有效期
- 公钥
- 证书所有者
- 签名
- …
当客户端获取到这个证书之后, 会对证书进行校验(防止证书是伪造的).
- 判定证书的有效期是否过期
- 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
- 验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等. 如果相等, 则说明证书是没有被篡改过的.
fiddler如何实现抓包HTTPS?
fiddler其实就是在进行中间人攻击!!!首次勾选 fiddler 的 https,提示是否要安装一个 xxxx 证书,这个是 fiddler 为了中间人攻击,自己生成的证书,得安装了这个证书,浏览器才会信任 fiddler,浏览器才不会弹框。
上述的这些过程,不是 HTTPS 独有的!!!这个过程是 SSL/TIS 的加密流程。
HTTPS 就是 HTTP + SSL,其他的协议也可能使用 SSL (比如 SSH协议)
总结
- 第一组(非对称加密): 用于校验证书是否被篡改. 服务器持有私钥(私钥在注册证书时获得), 客户端持有公钥(操作系统包含了可信任的 CA 认证机构有哪些, 同时持有对应的公钥). 服务器使用这个私钥对证书的签名进行加密. 客户端通过这个公钥解密获取到证书的签名, 从而校验证书内容是否是篡改过.
- 第二组(非对称加密): 用于协商生成对称加密的密钥. 服务器生成这组 私钥-公钥 对, 然后通过证书把公钥传递给客户端. 然后客户端用这个公钥给生成的对称加密的密钥加密, 传输给服务器, 服务器通过私钥解密获取到对称加密密钥.
- 第三组(对称加密): 客户端和服务器后续传输的数据都通过这个对称密钥加密解密.
其实一切的关键都是围绕这个对称加密的密钥. 其他的机制都是辅助这个密钥工作的.
- 第二组非对称加密的密钥是为了让客户端把这个对称密钥传给服务器.
- 第一组非对称加密的密钥是为了让客户端拿到第二组非对称加密的公钥
Tomcat
Tomcat 是什么
Tomcat 是一个 HTTP 服务器.
HTTP协议是网页和服务器之间沟通的重要桥梁
客户端:网页/浏览器
服务器:Tomcat就是其中一个重要选项!
HTTP 服务器种类是非常繁多的,在Java圈子中,最知名的就是 Tomcat 。
后续去搭建一个网站,肯定要实现页面,也要实现服务器,实现服务器没必要从 TCP socket 这个级别来写,就有大佬们已经实现出了一些 HTTP 服务器,直接就可以处理 HTTP 的请求了,因此我们只需要基于现成的 HTTP 服务器来开发即可。
后续学习的重点内容,就是使用 Java 代码调用 Tomcat 提供的API,来实现网站的后台
下载安装
链接:https://tomcat.apache.org/download-80.cgi点击此处跳转
下载好之后的目录和文件:
- bin 是"二进制",目录下方的就是一些 “可执行程序”。(.bat 是给 Windows 使用的,.sh 是给 Linux 使用的)
当前搞好的 Tomcat 和系统无关,Tomcat 是基于 Java 写的,运行在JVM上
- conf:Config 的缩写,意思是 “配置”。(像空调空调支持很多种工作方式(制冷 制热 送风 除湿)只要使用遥控器,切换一下 “模式”)
类似的,应用程序也是如此,类似的,应用程序也是如此,这些功能,可能需要使用"遥控器"来进行切换。对于像 Tomcat, MySQL 等专门给程序猿使用的 “专业软件" 来说,使用的 “遥控器” 比较简陋,就是一个单纯的文件,修改文件内容,就可以完成功能的切换了。
-
lib:library,放了一些 Tomcat 运行过程中依赖的库
-
logs:存放 Tomcat 的运行日志的(运行日志:程序运行过程中,打印出来的信息。通过日志就可以记录当前的程序,运行中的"中间状态",日志起到的作用,就是记录程序的运行过程,给调试程序提供基本的支持!!)
-
webapps:放的是我们自己写的代码。(—个网站的后端代码,就可以称为是一个 “webapp”)
Tomcat 是一个通用型的 HTTP 服务器,自身是不带有“业务逻辑"的,咱们要写一个网站,就需要编写代码实现业务逻辑,再和 Tomcat 相结合。
Tomcat 的启动:
看到这个字样就启动成功了。
Tomcat 自身是一个基于 Java 实现的程序,要想能够正确运行,势必要依赖 “Java”,务必要保证你的电脑上是安装了 Java 的
Tomcat是一个HTTP服务器,当我们启动成功之后,就可以通过浏览器来访问 Tomcat 自带的页面
在浏览器输入 127.0.0.1:8080(或者 http://localhost:8181/ ) 即可访问 Tomcat 自带的页面
但是此处需要注意的是如果这个页面打不开,极有可能是 8080 端口被占用了,我们可以在 conf 文件中找到 server.xml ,把里面的 8080(也有可能是其他端口号,用记事本打开可以查看)改成不和其他端口冲突的端口号即可。
127.0.0.1 环回IP,表示当前主机,8080 则是 Tomcat 默认的端口号
启动Tomcat可以看到这里出现一些乱码
Tomcat 默认使用了 UTF-8 编码,而当前 cmd,则是跟随系统编码(Windows简体中文版,默认编码是GBK)
此处直接手动运行 Tomcat 只是一个权宜之计,后面学习过程中,是使用 IDEA 的插件来自动调用 Tomcat(日志显示在 IDEA 中)或者是在 Linux 环境下使用 Tomcat 。(这两种方式都不存在乱码问题)
Tomcat 最大的用途就是,可以把写好的代码,放到 Tomcat 中,然后就可以通过浏览器来进行访问了
我们在页面写一个 html 的文件,然后复制粘贴到 webapps/ROOT 目录中去,然后可以在目录中打开这个页面
同时,我们也可以在我们的 Tomcat 自带的页面中输入我们本地的路径打开这个窗口
- 第一种方式是 :直接双击HTML来进行访问
这是让浏览器直接打开一个本地文件.你得本地有这个文件才能打开
- 第二种方式是:在浏览器中通过IP地址+端口号的方式访问:
这个则是访问网络上的一个文件本地没这个文件也可以.(只不过当前此处的 IP 是环回 IP 还是访问的自己)
例如我们自己查看自己电脑的 IP 地址,在 cmd 中输入 ipconfig 查看自己的 IP。
查看到我自己的 IP 地址后,别人能否通过我的 IP 访问我这个文件呢?
答案是不一定的,如果我们在同一个局域网,你就可以使用这个 IP 来访问我的电脑上,不然是访问不了的。(两个设备都使用 WiFi 或者 网线就可以,但是一个是 WiFi 一个是 网线 ,那也不一定,得看路由器咋配置)
当前有了 Tomcat,相比于直接双击来说,给别人提供了访问我的能力,但是别人之所以不能直接访问我,是因为当前我的电脑没有公网 IP!!(公网 IP:最靠谱的方法,就是搞一个云服务器)
Tomcat 不仅支持静态页面(页面的内容,是固定不变的),也支持动态页面(页面内容会根据用户输入的不同,产生差别)
动态页面:页面内容不同,格式基本相似。无论搜啥,本质上都是同一个页面,只不过页面里填充的数据内容不一样。
往 Tomcat 中部署的页面,不仅可以是 HTML,还可以带一些依赖,比如 CSS/JS/图片…
万一要部署的内容很多,此时如果都往一个 ROOT 目录中丢,就非常的不科学了!!容易很乱!!!
更推荐的做法,在webapps里单独搞一个目录(此时访问这个页面,就需要加上一级路径)
如果这里的地址写错了,忘了加目录名字,此处就会出现 404
把之前前端代码拷贝到 webapps 中
名字最好是英文
往这个目录拷贝新内容的时候,理论上 tomcat 是可以自动感知到变化,加载新内容但是 Windows Tomcat 有时候会有 bug,导致没有感知到(手动重启一下即可)
上面介绍的是通过Tomcat部署静态页面
Tomcat 的动态页面就要更复杂一些了,就涉及到了关于 Tomcat 提供的 APl --> Servlet
我们可以基于 Servlet 编写代码,部署到 Tomcat 上,就是动态页面了