目录
1)首行首行)
2)请求头请求头)
3)空行空行)
4)正文(body)正文(body))
1)首行首行)
2),响应头,响应头)
3)空行空行)
4)正文正文)
(2)Content-Length/Content-Type
1)引入对称加密引入对称加密)
2)传输对称密钥给服务器传输对称密钥给服务器)
3)引入非对称加密引入非对称加密)
4)中间人攻击中间人攻击)
5)引入证书机制引入证书机制)
一,HTTP
1,基本概念
HTTP(超文本传输协议):HTTP不仅可以传输文本,传输音频,传输视频,传输其他各种数据.⽬前我们主要使⽤的还是 HTTP1.1,https可以认为是http的升级版,和HTTP的区别就在于引入了一个"加密层"(https的安全性更高一些),HTTP是一种典型的"一问一答"模型.
一问多答:下载一个大的文件;一问多答:上传一个大的文件;多问多答:远程操控
2,HTTP抓包:
HTTP的报文格式:利用抓包(把网卡上的数据,获得到并且显示出来)工具,观察HTTP请求/响应的详细情况,TCP/UDP也是可以进行抓包的,日常开发中,很少会抓TCP层次的包,但是抓HTTP的包就会比较常见.抓包程序实际上就是一种代理.
代理又分为正向代理和反向代理,为客户端进行代理,称之为"正向代理",为服务器代理进行代理的就称之为"反向代理"
(1)wireshark
wireshark:功能非常强大,可以抓TCP,UDP,IPHTTP....
(2)Chrome/edge开发者工具
Chrome/edge开发者工具:(F12)自带抓包,但是没有办法看到HTTP原始报文数据,不太适合初学者
(3)fiddler:
使用的时候电脑上要退出其他的代理类软件,fiddle也是代理,所以可能会和其他代理冲突
1)左侧是抓到的HTTP数据包的列表
2)点击列表的某一项,就会显示出请求和响应的详细情况
右上角是请求详情
右下角是响应请求
通过选择请求和响应的raw选项得到原始HTTP.之后你会看到响应里有乱码,这里是二进制数据,(本身响应是文本,此处的二进 制是压缩后的)返回的响应数据解压缩后,其实就是主页的HTML,raw标签页就是HTTP的原始数据,发送HTTP请求,就是往TCPsocket中,按照上述格式发送一段字符串.收到HTTP响应,就是从TCPsocket中,读出一段字符串再解析
压缩:rar,zip在二进制的角度对数据进行重新编码,保证信息不变,体积缩小,体积小了,所消耗的带宽资源就少了,所以压缩就相当于用CPU资源换取带宽资源
浏览器中看到的网页,主要就是有HTML,CSS,JavaScript构成,返回一个HTML给浏览器就是HTTP非常典型的场景
3,HTTP请求和响应的基本格式:
行文本格式的协议
请求:
1)首行
首行:
"GET"->HTTP请求的方法;"https://www.sougou.com"->URL访问的资源是什么;"HTTP/1.1"->版本号
URL:唯一资源定位符
URI:唯一资源标识符
2)请求头
请求头:从第二行开始到空行结束
HTTP中,请求头里面的键值对都要哪些,是HTTP标准规定,都是具有特殊含义的
3)空行
空行:请求头的结束标志
4)正文(body)
正文(body)有的请求中有body,有的没有
HTTP一般来说,GET往往是不带body,但是POST往往是带body
响应:
1)首行
首行"HTTP/1.1"->版本号;"200"->状态码(成功/失败/失败的原因);"OK"->状态码描述
2),响应头
响应头:键值对,每一行是一个键值对,以空行结尾,键和值之间用空格分割,键值对也是有使用规范的,有的键值对只能在请求中出现,有的只能在响应中出现
3)空行
4)正文
正文:对响应来说,正文通常是HTML/CSS/JS/图片/音频....
4,唯一资源定位符(URL)
URL:唯一资源定位符,不是HTTP专属的,很多协议都会用到
协议方案名:URL给那个协议使用
登录信息:目前来说见不到了,当前没有网站使用,这样的方式来进行身份验证
服务器地址:可以是IP地址也可以是域名地址
服务器端口号:IP地址是确定为一主机,端口号是确定主机上的应用程序,不写的话,浏览器会自动拼接上一个端口,这个端口号是根据协议内容来定的,如果是http协议,则路由器自动加上的80端口号.如果是https协议,浏览器会自动加上443端口号
**带层次的文件路径:**确定服务器上的具体资源
查询字符串(query String):键值对结构,针对访问的内容进行补充说明,这是程序员自定义的键值对,和请求头/响应头不同,键值对之间用&分割,键和值之间用=分割
片段标识符:表示一个页面中的某个部分,常见于文档类
url encode:query String键值对结构,值可以包含各种内容,万一你的值里面包含了一些特殊的符号,可能会使URL解析出现问题,url encode本质上就是"转义字符",将有歧义的特殊字符用特殊的规则给替换掉
转义规则:把要转的符号/汉字.以每个字节十六进制的方式表示出来,给每个字节前面都加上%就可以了
将"+"这样的符号转译成%2B
5,HTTP的方法:
GET
GET从服务器获取资源
1)直接在浏览器中输入URL,就会触发GET请求
2)HTML页面中很多元素会进一步触发GET请求
当前看到这些请求,都是由搜狗HTML进一步触发的,HTML包含一些link,script.....都有可能进一步触发HTTP GET请求,进一步从服务器中获得资源,访问一个网页并不是一次HTTP请求就可以搞得定,是由多个HTTP请求结果汇聚而成的
浏览器缓存,上述得到请求的内容,都是一些CSS文件,JavaScript文件,图片,字体文件等(一般来说这种内容都是固定的)只要访问一次主页的时候,就把上述固定资源都保存下来(保存到电脑的硬盘上)后续访问的时候,就没有必要重复上述内容(重复获取的到的内容是一样的)上述机制,就称之为"浏览器缓存"这样可以节省带宽,加快界面展示速度,所以当按F5刷新的时候,抓到的请求不会很多,但是当按Ctrl键+F5时,就会忽略缓存,重新获取请求.
3)js代码中也能触发GET请求
POST:
1)登录/注册
2)上传文件
其实,HTTP中的GET和POST在很多场景中都是可以通用的
GET和POST的区别:
其实两者没有本质的区别(GET可以使用的场景,换成POST也可以,POST可以使用的场景,用GET,也未尝不可)但是在使用习惯上还是有区别的:
(1)语义不通:方法表示的含义,GET表示从服务器拿一个数据,POST表示往服务器提交一个数据
(2)传递数据的方式不同,GET传递数据,通常是通过query String把自定义数据交给服务器,POST传递数据,通常是通过body把自定义数据交给服务器
(3)GET方法对应的请求,通常设计成"幂等"的,但是POST方法对应的请求,对于"幂等性"没有要求(HTTP标准文档建议的做法),幂等特点是其任意多次执行所产生的影响均与一次执行的影响相同。所以类似转账,支付对准确性有要求的就偏向于使用幂等性,但是类似于广告数据就是不具有幂等性的,而是通过实时计算的.
此外,如果GET设为幂等性,则GET的结果可以被缓存,POST不设为幂等性,POST不应该被缓存
一下是一些具有争议的说法:
1,是否POST比GET更具有安全性??
答:不一定,安全性主要看中的是加密传输的方法和数据库存储的方式,并不是看重要信息在body中存储还是在query String中存储
2,GET传输存在上限,但是POST传输数据没有上限(body的长度没有限制)??
答:在HTTP标准文档中对URL的长度没有限制,只是在过去IE浏览器曾对URL进行过限制,造成的某种刻板印象.况且当前主流浏览器本质上都是Chrome内核,而非IE使用的内核
3,传输数据类型,GET只能传输文本,而POST文本二进制都可以??
答:也可以让GET传输文本,法一:基于query String ,可以把二进制进行UrlEncode/base64转码.法二:可以给GET加body.只需要确保使用的库(客户端,浏览器)支持这种用法即可.
在进行web开发的时候有一种restful设计风格,不同的方法表示不同的语义.增:POST,删:delete,查:GET,改:put
6,认识报头
认识报头(header ):header 的整体的格式也是 "键值对" 结构. 每个键值对占⼀⾏. 键和值之间使⽤分号分割键值对:
(1)Host
Host:表示服务器主机的地址和端口,这部分信息已经在URL有所体现
(2)Content-Length/Content-Type
Content-Length/Content-Type:前者表示body中数据的长度,单位是字节.后者表示body中数据格式.一个请求/响应中,没有body,也就没有这两个键值对,但是如果有body,就必须有这两个字段,由于HTTP是基于TCP的,所以存在粘包问题,这里的解决方法就是指定分隔符,指定数据包长度,如果HTTP数据包没有body,那么空行就相当于分隔符了,但是如果HTTP数据包有body部分,此时就需要Content-Length描述body部分的长度了,浏览器会根据Content-Type来决定如果解析body内容
编写一个网站:需要两个部分1,前端:网页,浏览器上给用户看到的部分;2,后端:服务器,网页上的数据来源于服务器.->当前网络前端HTML描述了网络的页面结构[一只蛤蟆一张嘴,两只眼睛,四条腿],CSS描述了页面样式[嘴是怎么样的,眼睛是怎么样的]JS描述了页面行为[如果与用户进行交互]
(3)User-Agent (简称 UA)
User-Agent (简称 UA):表示操作系统的信息和版本和浏览器的信息(表达了你用了什么设备上网)
判定UA确定用户浏览器的信息和操作系统的信息,从而判断当前用户版本的浏览器都支持那些特性,是只支持文字还是支持多媒体,也可以通过该信息判断出用户使用的是电脑还是手机.但是平板和手机的UA是一样的,所以就很难使画面针对不同屏幕进行适配,所以前端工程师就开发出了"响应式编程",可以在前端代码中CSS,自动查询出当前屏幕的尺寸,然后结合尺寸自动对页面进行重新排版.UA也可以用来做数据统计,主要用来区分PC和移动端..
(4)Referer
Referer:表示当前页面从哪个页面跳转过来的,如果你是直接在地址栏输入URL/点击收藏夹就不会有Referer
Referer是在HTTP请求中,发送给服务器的,给服务器使用的.例如:同一个广告主会给多个平台投放广告,在百度上点击,会跳转到广告主的网址,在搜狗上点击,也会跳转到广告主的网站,,这时广告主就可以通过Referer来区分那些点击是来自于百度,那些来自于搜狗.但是在多年前,运营商有可能会对Referer进行修改(运营商劫持),因为HTTP的请求都是通过运营商的设备"路由器"进行转发的.为了解决上述问题,就需要对Referer进行加密,所以https大规模普及.
浏览器回退,这时浏览器自身的行为,相当于浏览器自身维护了一个"栈"这样的数据结构
(5)Cookie
Cookie:也是键值对结构,使用;来区分,使用=分割键和值,键值对的含义是程序员自定义的,上述这些键值对,看似是从浏览器发送给服务器,但实际上这些数据都是从服务器返回浏览器,这些数据就相当于在浏览器本地存储的,为了安全,浏览器禁止网页直接访问你的硬盘(文件系统),但是浏览器并没有把路完全堵死,而是开了一个口子,允许网页通过键值对的方式来储存数据(这样的数据本质上也是存储在硬盘上)具体这样的键值对是如何存储到硬盘上的,浏览器封装好的,网页本身无法干预
浏览器首次访问某个浏览器的时候,发出的请求是不带有Cookie,服务器就会在返回的响应中带有Set-Cookie响应头,这时,浏览器收到的Cookie储存到硬盘上,等到再次浏览器访问服务器时,发出请求时就会带上Cookie
Cookie这样的键值对是按照域名维度来分类的,一个域名下有很多个Cookie,后续访问那个域名就把这个域名下的Cookie带入到请求中
为什么从服务器把Cookie发给客户端,客户端又把Cookie发给服务器呢??
答:Cookie在客户端和服务器两边都要使用
有一个Cookie非常经典使用场景,使用Cookie保存用户信息,
会话ID:是由服务器生成一个随机的为一的字符串,服务器同时会生成一个类似于hash这样的数据结构,以会话id为key,以用户的详细信息(用户名,真实姓名....)为value
在登陆成功后再次进行页面访问,就会在请求中发送Cookie,这时服务器收到Cookie之后,就会读取里面的sessionld对应上面的hash中进行查询,这样就可以快速的知道当前用户的身份是什么
随着互联网的发展,Cookie也不是唯一一个可以在浏览器这边存储数据的机制了,例如还有local storage (键值对方式存储),index db(类似于表这样的结构存储)登录信息验证时,也不一定都是基于session这样的方式进行存储,也有一些其他的方式,比如业界比较流行的jwt的方式,就是用户的信息存储在客户端,但是加密一下
(6)"状态码"
状态码存在于响应的报头中
strerror:把错误翻译成一个字符串,这是C语言中的一个概念erron(error number)
200 OK. 表示请求成功.
404 not found浏览器访问的资源没有被找到,这时响应的内容是由程序员自定义的
403 Forbidden,访问被拒绝(没有权限)
405 Method Not Allowed方法不支持(例如网站接受GET,却收到了一个POST)
500 Internal Server Error服务器代码出现bug.(一般情况为代码内部抛出了异常,但是没有catch到)
504 Gateway Timeout响应没有在规定时间内返回,属于服务器出现问题了
302 Found 重定向 访问网站A,自动跳转到网站B,响应返回这样的状态码,并在响应头中添加Location属性(包含了B网站的网址)[例一:点击广告,把请求发到浏览器,然后浏览器跳转到广告主的网站,(方便统计数据).例二:服务器迁移域名,就会把旧的域名设置为302,跳转到新的服务器]
一般情况下:4--一般是客户端的问题,5--一般是服务器的问题
7,body.
8,构造HTTP请求的方式:
法1,HTML from标签
法2,JavaScript Ajax
法3,Java Socket API
新手可以采用postman易于上手,而且可以自动编译生成代码,也可以采用apifox,其功能强大,它将HTTP请求和"接口文档"(只是一种约定,核心为内容,格式不限)结合起来
二,HTTPS
HTTPS是的使用是非常普遍的,HTTP是明文传输.由于运营商和黑客可能会进行劫持,所以https是加密密文传输,https是在HTTP的基础上引入了一个加密机制
1,基本概念:
1,明文:传输的原始数据
2,密文:把明文进行加密
3,加密/解密:明文->密文;密文->明文
4,对称加密:无论是加密还是解密共用一个密钥
5,非对称加密:一对密钥(从数学角度生成一对密钥),一个公开称之为=>公钥每一个私密称之为=>私钥.
2,https的基本工作流程:
1)引入对称加密
但是由于,每一个客户端连上服务器的时候都要有一个自己的密钥,所以需要把密钥发给服务器
2)传输对称密钥给服务器
但是黑客还是可以在这个过程之劫持密钥,从而来破解密文
3)引入非对称加密
引入非对称加密,辅助对称加密,传输业务的数据还是使用对称加密,非对称加密只用来传递密钥(原因:非对称加密开销比较大,性能要求较高)
4)中间人攻击
上述流程中任然存在缺陷
在服务器生成一对密钥,这时候客户端发出请求(公钥是什么?),然后服务器将公钥pub1传给路由器,这时候路由器被黑客攻击,对pub1进行劫持,并且自己生成一对密钥,然后将自己生成的公钥pub2发送给客户端,这时,客户端用pub2对秘钥进行加密,并发给路由器,这时候黑客用自己的私钥pri2对pub2 进行解密,获得密钥,然后再用pub1对密钥进行加密,发送给服务器.在这个过程中,黑客就可以获取传输业务数据的密钥.从而获得业务数据
5)引入证书机制
证书机制,引入了第三方机构,如果想要搭建服务器,使用https就需要在公正机构里申请证书,根据网络域名,营业执照,公钥...各种信息,公正机构就可以根据这些信息生成一张"电子证书",电子证书中一项"签名",签名是校验和加密形成的.签名是证书合法性的关键点.服务器申请到证书之后,客户端从服务器拿的就不再单单是公钥,而是整个证书.客户端收到证书后就会对证书进行校验.
证书中所有字段综合到一起,计算校验和,再对校验和进行非对称加密,如果客户端进行校验的时候,数据和原始数据相同,那么校验和相等,反之,如果,与原始数据不同,那么校验和不同.
公正机构会自己生成一对密钥,公正机构保存好自己的私钥,将公钥发给不同的客户端,操作系统和公正机构合作,客户端手里的公钥是操作系统内置的,而非仅仅通过网络传输获取的.这就确保了公钥的安全性.[客户端会验证这个证书中的公钥是否与本地存储的公钥一致。一旦验证通过,客户端就可以使用这个公钥进行加密通信]
当服务器将证书发给了客户端后,客户端会验证数字签名:
(1)将证书中的各个字段再算一次校验和,得到checksum1
(2)客户端用公钥,对数字签名进行解密,得到checksum2,
(3)比较checksum1和checksum2,若相等,则证书合法,如果不相等,则意味着证书被篡改过了,这时网页就会给出一个明显的警告,提醒用户不安全.
3,为什么fiddler可以解析https?
只有拿到密钥,才可以对数据进行解析,这就相当于用户自己进行中间人攻击(fiddle是一个代理,相当于数据要从这里经过转发在再到达客户端)
fiddler会对浏览器服务器证书进行篡改,相当于生成自己的证书(把服务器的公钥替换成自己的公钥,并重新计算校验和,并用自己的私钥进行加密,得到数字签名),由于我们在设置fiddler时候,设置了相信fiddler提供的证书,所以就可以通过fiddler的证书的公钥与本地公钥比较的验证.然后计算checksum1,同fiddler解密checksum2,进行对比.对比通过后,就会用fiddler公钥对密钥进行加密,发给fiddler.fiddler得到密钥.后再用服务器的公钥进行加密.
三,总结(经典面试题)
在浏览器输入URL,得到最终展示的页面为止,这个过程计算机做了什么???
1,从网络原理角度
(1)DNS域名解析
(2)https握手(对称加密/非对称加密)
(3)HTTP 请求 响应
(4)TCP三次握手/四次挥手....
(5)IP,地址管理,路由转发
(6)数据链路层 以太网
2,服务器后端
(1)服务器如果处理HTTP请求(Spring)
(2)根据请求计算响应
(3)响应返回客户端
分布式系统/微服务架构
a,网关 b,分发给应用服务器 c,分发过程 服务发现,负载均衡 d,应用服务器有涉及操作系统,数据库.... e,服务器之间通过rpc交互
3,前端角度