HTTP / HTTPS
- HTTP概念
- HTTP协议格式
- HTTP请求
-
- URL
- 方法(method)
- 请求报头
-
- Host
- [Content - Length](#Content - Length)
- [Content - Type](#Content - Type)
- User-Agent
- Referer
- Cokie
- HTTP响应
- HTTPS
HTTP概念
HTTP被称为超文本传输协议,文本是字符串 ,超文本也就是能传输的不仅仅是文本,也可以是一些图片、视频等等,其可以传输二进制数据


HTTP是目前主流的一种应用层协议
这里HTTP1.0 、HTTP1.1 、HTTP2.0都是基于TCP实现的,但是HTTP3.0是基于UDP实现的(因为TCP比较有些影响性能)
使用https://www.bilibili.com/ 打开网页,但是发现这里并不是http,而是https,其本质上还是http,只是在这个基础上,引入了"加密层 ",能够实现"安全传输 "
当输入这个网址的时候,浏览器就会可能给服务器发送多个HTTP请求 ,服务器就会对应返回多个响应 ,像这里的界面 html、css、javaScript,还有一些图片、文字等信息

HTTP是典型的一问一答的模型,客户端发一个请求,服务器就发一个回应
像访问一个网站时候,可能涉及多个HTTP请求/响应
HTTP协议格式
HTTP是一个文本格式的协议,可以通过一些工具进行抓包,这里Fiddler工具比较适合HTTP抓包


配置一下
抓取访问搜狗浏览器的这个包
此时这里的Fiddler相当于一个代理 ,浏览器先把请求发给Fiddler,Fiddler再将请求发送给sogou服务器,并且返回数据,也是先给Fiddler,再返回给浏览器,因此有时候可能因为抓包工具导致请求一些东西超时



协议格式
请求首行:方法 + url + 版本
响应首行:版本号 + 状态码 + 状态解释器
如果没有这个空行,可能回出现"粘包问题"


HTTP请求
URL
Uniform Resource Locators统一资源定位符
在这个互联网上每一个文件都有一个唯一的URL,里面会指出文件位置以及浏览器如何处理等等,URL的格式是被约定了

http :协议方案名 ,有http 、 https等,也有其他类型
user : pass : 登录信息 ,但是现在都是采用一个界面方式输入登录信息,所以这个可能被省略
www.example.jp : 服务器地址 ,可以是域名 ,也可以是IP地址 ,通常使用域名
80 :是服务器端口号 ,如果没填浏览器会给一个默认的,http默认80,https默认443
dir / index.htm : 带层次的文件路径 ,通过一定的目录结构来组织资源,这里可能是真实的目录结构,也可能是"虚拟的目录结构"
uid = 1 :查询字符串(query string)本质是键值对结构,&分割键值对,=分割键和值
#ch1 :片段表示符,用于页面跳转,一个页面的不同部分
query string键值对结构,里面的key和val是由程序猿决定的
片段标识符
在Vue里有展示

URL encode
对于query string 来说,有时候需要进行encode转码
一些特殊字符,像 / ? :等这样的字符,在这里面是有特殊的含义,这样字符不可以随意出现,因此需要对这些字符进行转义,中文字符也是需要进行转义的


转义规则 :将转码字符转换成16进制,从右向左取出4位进行处理(不足的话直接取),两位作为一位,在其前面加 %

像这里 + 转义成 %2B
urldecode就是解码,urlencode是编码query string获取数据
方法(method)

GET获取 :就是从服务器上获取某个资源
POST投递 :将数据投递到服务器上
PUT放过去 :将数据往服务器上投递
DELETE删除 :删除服务器上资源............
虽然这里有每个方法都有自己的含义,但是这并不是强制要求,因此这里GET方法是最常用的
GET方法
GET常用于HTTP方法,常用于获取服务器的某个资源
GET请求通常是没有body (存放的一些程序猿自己定义的一些数据)的,但是也可以有
query string 可以为空,也可以不为空
header部分有若干键值对结构
例如访问搜狗浏览器
此时想要获取某个数据可以通过url中的信息,获取其路径 和 其query string




POST方法
用户输入数据给服务器
query string 一般为空,也可以不为空
header有若干键值对结构
body一般不为空
登录和上传文件容易出现POST
登录login


上传文件更改头像


GET和POST的区别
没有"本质区别",能用于GET的地方一般也能用于POST,能用POST的地方一般也能用GET
1.GET一般用于获取数据,POST一般用于上传数据
2.GET通常将要传输的数据放入query string中(body一般为空),POST通常放在body中(query string一般为空)
还有一些有歧义的说法
1.幂等 :GET请求一般实现"幂等 ",POST请求"没有幂等 "
幂等在计算机意思就是如果这个请求重复产生之后,其结果是明确的,这就称为幂等
反之就是都是GET相同,但是返回内容不同就是没有幂等
在官方文档中只是建议这样设置 ,但是并没有强制要求
2.GET可以被缓存,POST不可以被缓存
这里和上面幂等一样,之所以其会相同请求,出现相同结果,是因为其对着一些数据进行了缓存 ,反之则没有
3.安全 :GET请求不安全,POST请求安全
像前面的登录,如果是GET的话会将这些信息放在query string会直接显示出来
POST会将这些登录信息放在body中
并不是展示出来就不安全,没展示出来就安全,还是安不安全取决于你是否对这些数据进行加密
4.传输数据量 :GET传输的数据量⼩,POST传输数据量⼤
以前的浏览器对起url有长度限制,但是现在的URL可以很长 ,这里主要取决于不同浏览器和服务器的实现区别
5.数据传输类型 :GET请求只能传输文本数据,POST可以传输文本和二进制文件
URL中的确不可以直接放二进制,但是起可以通过urlencode / base64转成文本来进行传输
其他方法
PUT和POST类似,只是具有幂等建议
DELETE删除服务器数据指定资源
OPTIONS返回服务器所支持请求方法
HEAD和GET类似,只不过之响应之后,只返回头
TARCE回显服务器端收到的请求
CONNECT预留,暂不使用
请求报头
Host
表示服务器主机的地址和端口号

此处把域名中的IP地址和端口号拿出来,这样如果后面需要就可以直接使用
Content - Length
body的长度以字节为单位

Content - Type
表示的是body的格式
常见的格式有 text / html 、text / css 、application / javascript 、application/json、image / peg 、text / plain


这里告诉浏览器/服务器数据格式,这样服务器 / 浏览器知道如何解析这些数据
Content-Type:charset=utf-8这样可以设置起字符集编码,如果一些数据出现乱码就可能使编码方式不同的问题
User-Agent
表示浏览器和操作系统的属性
例如:这里访问搜狗浏览器
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0

浏览器会不断更新,但是仍然会有一些人使用一些老版本,因此这里可以通过这个操作系统信息 + 浏览器版本 ,知道版本就可以根据其对应版本可以接收的信息,针对性返回信息(一些新的版本功能可能比老版本强)
并且我们这里PC端和手机端,因为屏幕大小的问题,其需要判断其操作系统进行浏览器显示对应不同显示,但是这样就有问题就是如果更新新的版本就要两端都要更新
手机端

PC端

因为这样会更新两个版本的问题,现在有"响应式编程 ",就是可以根据浏览器窗口尺寸来进行不同的排版更换
Referer
表示的这个界面从那个界面跳转过来的
搜狗浏览器搜 时崎狂三
Referer: https://www.sogou.com/
搜索结果点击相对应链接
直接从浏览器中输入url是或者根据收藏夹访问页面是没有Referer
Cokie
存储的是一个字符串,可能是客户端通过网页自动写入的,也可能来自服务器经过响应写入的
用途 :浏览器给网页提供的本地存储数据的方案
从哪里来 :服务器返回
如何存 :按照字符串进行存(键值对)进行存储,根据域名维度进行划分
存哪里 :本地存储之后,后续访问同一域名的网站,就会把cookie的内容通过请求报头,传输给服务器
像这里在gitee网站中

并且这里可以对其Cookie进行删除
如果删除,下一次登录访问时候,其会Set-Cookie 将保存的Cookie传递过去
很多场景都是基于Cookie实现的,最核心功能是保存用户登录状态

Coolie和Session不是强相关的
即使是上面的登录场景
客户端但可以使用其他技术搭配Session,当然Cookie也可以有其他功能
HTTP响应
状态码
200:OK请求成功
404 NOT FOUND没找到,访问一个资源的时候在浏览器输入URL如果输入错误,可能就会出现这样的回应

403 Forbidden
表示拒绝访问,通常是一个用户需要具有一定权限才能访问
(像这里查看别人的gitee私有仓库,只有登录了账号才可以访问)

405 Method Not Allowed
HTTP有GET POST PUT DELETE等方法,但是并不是所有浏览器都有其全部方法,如果访问其没有的方法就会出现这个服务器不支持这个方法
500 Internal Server Error服务器挂了,内部出现了问题
504 Gateway Timeout服务器网关业务繁忙,出现了请求超时的问题
301Moved Permanently 永久重定向
302Move temporarily 临时重定向
"重定向"相当于跳转 ,我们访问url1,它跳转到了url2跳转的话响应报头header部分会包含一个Location,表示跳转到了那个页面
永久重定向就会访问到这种响应,后续请求都会自动改成新地址,和302类似需要通过Location

响应报头
和请求差不多
这里有Date表示时间
Content - Type 正文body数据类型
Content - Length数据长度

HTTPS
https是一个应用层协议,是在http协议基础上引入了一个加密层
因为HTTP协议内容都是按照文本方式明文传输的,这样传输过程中就有些数据就可能被篡改
被劫持的数据其一些链接会改变
这里未被劫持的数据这里下载链接是正常的

被劫持后,这个被修改成qq的链接


因为这里我们传输的数据传输会经过运营商网络设备,像路由器和交换机 ,此时运营商就可以对这些数据进行篡改
上面这里的下载链接,运行商就修改成了"qq浏览器"的下载地址

加密
上面这样明文传输很危险,因此就需要进行加密
加密 :就是把明文传输的数据经过一系列变换,生成密文
解密 :就是将密文经过一系列转换,还原成明文
在加密和解密过程中就需要一个或者多个中间的数据 来帮助这个过程,这里的中间数据被称为密钥
加密和解密后面发展成了密码学
艾伦·麦席森·图灵就是密码学的奠基人 ,也是计算机科学祖师爷之一


在二战时期,那时候都是采用无线电报传输数据,但是这样所有人都可以收到,因此德国就发明了恩格玛机 来采用机器加密,这样别人进行手工解密就会非常麻烦,于是图灵大佬就想到你用机器加密,那我也用机器解密来破解你的数据
HTTPS工作流程
这里要保证数据安全,就要对数据进行加密
网络传输不在是使用明文传输 ,而是传输加密之后的"密文 "
加密主要分为对称加密 和非对称加密
对称加密
一个"密钥",既可以加密,又可以解密
客户端和服务器都有这个"密钥"
客户端发送时候,就对数据进行加密,而服务器就可以使用"密钥"进行解密

这里黑客拿到的就是经过密钥加密的数据 ,并不知道里面是啥
但是一个服务器需要服务多个客户端,并且每一个客户端的"密钥"是必须不同的,如果相同容易被黑客拿到,因此服务器需要维护每个用客户端和服务器密钥之间的关联关系
因此这里就可以生成一个随机对称密钥,把这个对称密钥也通过网络传输过去 ,这样客户端和服务器都知道了对应密钥
但是这样把密钥明文传输 ,这样黑客就可以知道密钥 了,这样我们对称密钥就没有用了,有了密钥就可以对加密数据进行解密

那我们还需要一个新的密钥 对" 这个密钥 "进行对称加密传输过去 ,这样的话我们也需要将其新的密钥传输过去,这样我们因为明文传输的密钥需要加密,加密又有新的密钥是明文传输 ,这样就出现死循环了
黑客可以获取到新的密钥(明文传输),对原本密钥解密,有了原本密钥就可以对加密数据进行解密,这里就需要引入非对称加密
非对称密钥
解决对称密钥明文传输问题
这里有两个密钥,一个"公钥",一个"私钥"
公钥和私钥配套使用
可以通过公钥进行加密,通过私钥进行解密
当然也可以反过来,用私钥进行加密,用公钥进行解密
但是这个最大缺点是运算符速度非常慢
让对称密钥采用非对称加密 ,

此时我们就可以让服务器生成一个非对称密钥,通过这个非对称密钥来对 对称密钥加密
这样确保了黑客获取不到对称密钥,这样数据其就无法解密
但是为什么我们不全部都使用对称密钥呢?
主要是因为对称加密效率较高,占用资源较少
非对称加密效率较低,占用资源较多
并且这个非对称密钥也是随机生成的
中间人攻击


这里进行公钥给客户端时候,会被黑客修改成自己的一对非对称密钥,因此客户端的对称密钥就会根据黑客的自己的非对称密钥进行加密,此时返回给服务器时候,黑客就可以使用自己的私钥来解密,这样就获取到了对称密钥
引入证书
解决上面无法判断密钥是否来自服务器或者客户端
服务器https访问之前会向CA索要证书申请者信息、公钥信息
证书就像身份证,证明服务器的权威性
证书里面会有证书机构、证书有效期、公钥、证书所有者、签名
blog.csdnimg.cn/direct/ca451429b469427c9a5434a2a4f1caa6.png)


证书里面有个签名属性
签名本质是"加密的校验和 ",拿着原本的数据通过一定公式进行计算得到的一个值,如果原始数据相同,校验和相同,得到的数据也相同
因此这里黑客这个中间人问题,就得到了解决,因为客户端收到公钥 会使用同样算法 进行计算校验和 check1
客户端会拿着证书中的公钥 ,对签名进行解密 ,也会得到一个校验和check2
这里如果check1和check2相同,此时就说明证书是真的,反之证书是假的
这样如果这里公钥被黑客掉包,此时计算的校验和肯定不相同,因此就说明被篡改了
问题:
黑客可不可以也把数字签名也修改了
不行,因为此时数字签名是使用公正机构的一个私钥加密,它没有私钥,无法生成数字签名
黑客可以对公证机构传输证书的pub公钥进行中间人攻击吗
不可以,因为这里的pub公钥根本就不是网络传输的,大部分已经内置到了操作系统中