网络七层模型
-
物理层
使用一定物理介质 电信号
-
数据链路层
MAC地址 byte
-
网络层
IP协议
-
传输层
TCP(用户数据包协议)/UDP(传输控制协议) 端口
-
会话层
断电续传
-
表示层
翻译 解决不同系统之间数据传输的问题
-
应用层
HTTP协议
一个浏览器页面启动的时候启动的进程
最少启动了4个进程
- 浏览器主进程
- 渲染进程
- 网络进程
- GPU进程
- 插件进程(需要浏览器安装插件)
浏览器发送HTTP请求流程
- 构造请求行
- 查找缓存 有缓存用缓存,没有就发送网络请求
- 准备IP地址(网络层)和端口号(传输层)
- 等待TCP队列 一个域名最多只能建立6个TCP地址
- 建立TCP连接
- 发送HTTP请求
服务器处理HTTP请求
- 返回请求内容
- 断开链接
从输入URL地址到浏览器显示页面,这个过程发生了什么
进程的角度讨论
调用了浏览器的三个进程:浏览器主进程、网络进程、渲染进程
- 浏览器主进程输入url地址
- 浏览器主进程将url地址派发给网络进程
- 在网络进程中发送url请求,获取响应头数据,解析响应头数据转发给浏览器主进程
- 浏览器主进程将网络进程发送来的响应数据发送“提交文档”消息给渲染进程
- 渲染进程接收到消息之后,准备接收HTML数据,接收数据的方式是直接和网络进程之间建立数据管道
- 文档数据传输完毕,渲染进程会返回“确认提交”信息给浏览器主进程
- 浏览器主进程接收到渲染进程的“确认提交消息”之后,便开始便开始移除旧的文档,更新浏览器进程中的页面状态
三次握手
SYN代表建立链接:1发送链接消息、0确认链接消息
ACK代表响应确定:1确认消息、0不是一个确认消息
- 客户端向服务器发送SYN=1,进行建立链接
- 服务器向客服端发送SYN=1,ACK=1确定响应客户发送的建立链接的请求,并且发送建立链接的消息给客户端
- 客户端向服务器发送ACK=1确定响应服务器发送的建立连接请求
四次挥手
FIN=1:希望断开连接
RST=1:TCP连接出现异常,需要断开
- 客户端想断开,传递FIN=1给服务器
- 服务器向客户端响应ACK=1表示可以断开了
- 服务器做好链接关闭的准备后,发送FIN=1,ACK=1给客户端,此时服务器处于半关闭状态
- 客户端接收到服务器发来的FIN=1后发送一个ACK=1给服务器。经过2MSL(Maximum Segment Lifetime)后,没有收到服务器发来的报文,则确定B 主机已经收到A主机最后发送的ACK 指令,此时TCP连接正式释放。
浏览器的渲染流程
一个简单的html页面浏览器的渲染流程
DOM解析->CSS解析->样式计算->布局树->图层树->绘制->合并图层
- 将html解析为DOM树
- 将css解析为css树形结构
- 样式计算
- css+html生成布局树
- 根据布局树生成图层树(position:fixed/video标签/css 3d/css动画/canvas)
- 绘制(一个个绘制)
- 合并图层,生成最终的页面
没有通过link标签去引入css:css还是通过html解析器在解析,新开一个线程去解析css,还有一个线程去解析html。会阻塞浏览器的渲染,不会阻塞DOM解析
通过link标签引入css:link标签会阻塞浏览器的渲染,不会阻塞DOM解析
js会阻塞浏览器的渲染、阻塞DOM解析、阻塞JS的执行,尽量将js放在底部
重排layout
重新计算所有元素在窗口的位置,以图层为单位。重排一定会导致重绘
重绘paint
触发重绘的:元素样式的改变(不包含宽高、大小、位置)。触发重绘的属性:color、border-color、border-style、vsibility、background、background-image、background-image、background-position、background-repeat、outline
计算所有元素在窗口具体呈现内容,以图层为单位。一个图层发生重绘,在这个图层上的所有图层都会发生重绘,因为浏览器渲染页面时以图层为单位。重绘不一定导致重排
重绘和重排都会消耗浏览器的性能,将需要重绘或重排的元素单独设为一个图层:will-change:transform
重绘和重排优化方案
- 元素位置移动变换时尽量使用css3里面的transform配合图层来代替top left等操作
- 使用opacity配合图层使用既不触发重排也不触发重绘,代替visibility
- 将多次改变样式的操作合并成一次(不要一条条修改DOM样式,先定义好class,然后修改DOM的className)
- 利用文档碎片(documentFragment)
- 不要把获取某些DOM节点的属性值放在一个循环里面当成循环的变量(当获取文档的height、width会触发重排和重绘)
- 为动画元素新建图层
缓存
强缓存
- 不会向服务器发送请求,直接从本地缓存中获取数据
- 请求资源的状态码为200 ok(from memory cache)
协商缓存
- 向服务器发送请求,服务器会根据请求头的标识判断是否命中协商缓存
- 如果命中,返回304状态码通知浏览器从缓存中读取资源
响应头上加上Last-Modifie,这个参数是这个资源在服务器上最后修改时间,浏览器再次访问这个资源,在请求头上会加上If-Modifie-Since和Last-Modifie做对比,没有变化返回304 Not Modified,响应头不会再添加Last-Modifie,不会返回资源内容,有变化则返回资源内容
Etag/If-None-Match:内容不变仅仅修改时间改变,以内容为标识,解决Last-Modifie以时间为标识,进行判断是否重新请求
强缓存和协商缓存
共同点:都是从浏览器读取资源
不同点: 1. 强缓存不发送请求给服务器 2. 协商缓存发送请求给服务器,根据服务器返回的信息决定是否使用缓存
浏览器的网络和安全
http/0.9
只用传输html文件,传输的数据比较简单,只有请求行,没有请求头和响应头
http/1.0
引入了请求头和响应头、缓存机制、状态码、用户代理。解决多种类型文件下载。
http/1.1
持久化连接,用于提升连接效率。每个域名最多同时维护6个TCP链接。使用CDN的实现域名分片机制。对带宽利用不理想(TCP 慢启动、同时开启多条TCP连接,这些连接会竞争固定的带宽、http/1.1的队头阻塞问题)
http/2.0
多路复用(一个域名只使用一个TCP长连接来传输数据),消除队头阻塞问题。可以设置请求的优先级。服务器推送。头部压缩。
浏览器的安全
页面安全
同源策略、xss(跨站攻击)、CSRF攻击
同源策略
url协议、域名、端口号都相同,则为url同源。浏览器默认两个同源之间可以相互访问资源和操作DOM,不同的源是不能相互访问资源操作DOM的
XSS攻击
往HTML文件中或DOM中中注入恶意脚本,从而在用户浏览页面时,利用注入的恶意脚本对用户实施攻击的一种手段。
恶意脚本注入,有以下几种:存储型XSS攻击,反射型XSS攻击,基于DOM的XSS攻击
`存储型XSS攻击`
利用网站漏洞,将一段恶意的js代码提交到网站的服务器
之后用户访问页面时,发送请求中包含了恶意的脚本
当用户访问浏览器页面时,恶意脚本就会将用户的Cookie信息等数据上传到恶意的服务器
`反射型XSS攻击`
恶意脚本属于用户发送请求的一部分,随后服务器又把恶意脚本返回给用户。当恶意脚本在用户页面中被执行时,就可以利用恶意脚本做一些操作
`基于DOM的XSS攻击`
不会牵涉到页面Web服务器的。通过各种手段将恶意脚本注入用户的页面中,比如通过网络劫持在页面,修改页面。
阻止XSS攻击
-
服务器对输入的脚本进行过滤和转码
-
充分利用CSP技术,CSP有如下功能:
- 限制加载其他域下的资源文件
- 禁止向第三方提交数据
- 禁止执行内联脚本和未授权的脚本
- 提供了上报机制,有助于发现有哪些XSS攻击,以便修复问题
-
使用HttpOnly属性
大部分XSS攻击都是盗用Cookie,将HttpOnly设置为true时,无法通过脚本读取到cookie的数据
CSRF攻击
跨站请求伪造;伪造请求,冒充用户在站内的正常操作。攻击者盗用用户的身份,以用户的名义发送恶意请求。
防止CSRF攻击
发起CSRF攻击的三个必要条件:
- 目标站点一定要有CSRF漏洞
- 用户登陆过目标站点,并且在浏览器上保持该站点的登陆状态
- 用户需要打开第三方站点,可以是黑客网站,也可以是一些论坛
-
充分利用好Cookie的sameSite属性
-
验证请求的来源站点
可以使用HTTP请求的Referer和Origin
-
CSRF Token
- 浏览器向服务器发送请求时,服务器生成一个CSRF Token(是服务器生成的字符串),然后将字符串植入到返回的页面中
- 在浏览器如果需要发起转账请求时,带上页面上的CSRF Token。服务器验证是否合法