浏览器总结
# 浏览器兼容性问题
CSS Hack
CSS hack是通过在CSS样式中加入一些特殊的符号也就是浏览器前缀,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的,CSS hack就是让你记住这个标准),以达到应用不同的CSS样式的目的。
主要是为了兼容IE低版本
polyfill
polyfill 是一段代码(或者插件),提供了那些开发者们希望浏览器原生提供支持的功能。程序库先检查浏览器是否支持某个API,如果不支持则加载对应的 polyfill。比如,html5的storage。不同浏览器,不同版本,有些支持,有些不支持。
PostCSS
可以理解为CSS的
Babel
工具,拥有强大的插件生态系统来分别做不同的任务.
上述都可以在webpack打包中配置使用.
# 浏览器优化
减少http请求次数:精灵图、base64格式、使用HTTP2、善用强缓存、协商缓存
减少传输时间:cdn、gizp压缩
减少渲染时间:减少回流(重排的次数)、开启服务端渲染
图片优化:懒加载、base64格式、使用webp格式图片
dom操作方面:尽量少操作、使用事件委托
js引擎方面:使用事件委托操作dom、使用web worker进行长时间脚本的运行
# 浏览器安全
跨站脚本攻击(XSS:Cross Site Script 为了与css区分)
解释:是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害用户的数据安全。
XSS 的本质
是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。- 存储型 XSS 攻击:黑客将恶意代码储存到存在漏洞的服务器,浏览器访问含有恶意代码的页面,浏览器上传用户信息到而已服务器。
- 反射型XSS攻击:用户将一段含有恶意代码的请求提交给 Web 服务器,Web 服务器接收到请求时,又将恶意代码反射给了浏览器端,这就是反射型 XSS 攻击。
- 基于 DOM 的 XSS 攻击:通过修改原始客户端脚本所使用的DOM环境(在受害者的浏览器中)来执行有效负载。也就是说,页面本身不会更改,但由于对DOM环境的恶意修改,页面中包含的客户端代码以意外的方式运行。
防范:
- 对用户的输入进行转义
- 开启HttpOnly:true、验证码机制,防止脚本冒充用户
- Content-Security-Policy:响应头字段(csp内容安全策略,指定有效的域、即只执行哪些js脚本,来防止攻击)
跨站请求伪造(CSRF:Cross-site request forgery)
解释:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的
防范:
- 请求来源认证,在HTTP请求头中有一个字段叫Referer,它记录了请求的来源地址。 服务器需要做的是验证这个来源地址是否合法,如果是来自一些不受信任的网站,则拒绝响应。
- token:使用
tocken
来代替cookie - cookie字段设置
HttpOnly:true
,恶意脚本则无法通过js脚本获取修改cookie - cookie字段设置sameSite: strict,cookie在跨站请求时不会被发送
# 面试题
从输入URL到页面加载的全过程。
网络请求资源阶段
构建请求,查找强缓存(根据Expires、Cache-Control头)
DNS解析
从域名 -> IP地址的解析。如果域名已经被解析过,那么会查找缓存。具体的经历是
浏览器缓存 -> 本地hosts文件 -> 本地DNS解析器 -> 本地DNS服务器 -> 其他DNS服务器
建立TCP连接
注意,Chrome在同一个域名下最多只能有6个TCP连接,超过则需等待。
- 通过三次握手建立客户端服务器的连接。
- 数据传输
- 断开连接,四次挥手
是否建立https连接
发送HTTP请求(数据传输还未开始)
携带请求行、请求头、请求体向服务器发送请求。
网络响应
网络响应也包含了三个部分:响应行、响应头和响应体。
当响应结束后判断
Connection
字段,判断是否未keep-alive
连接,若是则是建立的持久性连接.
浏览器解析渲染资源阶段
浏览器接收数据
一般响应头的
Content-Type
的值是text/html
,那么浏览器便开始进行解析和渲染工作构建dom树
将一系列的字节流转换为dom树的数据结构,本质上是一个以
document
为根节点的多叉树.解析HTML(非上下文无关文法)
:标记化算法=>构建tokens样式计算
格式化样式表
:stylesheets(因为浏览器看不懂css样式文本,所以将其转换成结构化的对象,可以通过document.styleSheets查看)标准化样式属性
:比如rem
->px
,bold
->700
等等计算具体样式
:比如继承的样式
构建
Layout Tree(布局树)
遍历生成的 DOM 树节点,并把他们添加到
布局树中
。- 计算布局树节点的坐标位置。
对于
head
标签和设置了display: none;
的元素并不会放入其中建图层树
浏览器在构建完
布局树
之后,还会对特定的节点进行分层,构建图层树。一般情况下,节点的图层会默认属于父节点的图层,(这些图层也被称作合成层),而有的节点会提升成一个单独的合成层。
显示合成
拥有层叠上下文的情况
HTML
根元素普通元素设置了
z-index
属性,且其position
属性不为static
opacity
属性值不为1设置了
transform
属性设置了
filter
属性设置了
will-change
属性需要裁剪的地方
比如一个div,只有50x50大小,但是放置了很多的文字,那么就需要将超出的文字裁剪。
隐式合成
接下来是
隐式合成
,简单来说就是层叠等级低
的节点被提升为单独的图层之后,那么所有层叠等级比它高
的节点都会成为一个单独的图层。所以若是嵌套的层级太深,就有可能发生层级大爆炸
!当然单独的图层在重绘的时候只会影响本身。
绘制列表
接下来渲染引擎会将图层的绘制拆分成一个个绘制指令,比如先画背景、再描绘边框......然后将这些指令按顺序组合成一个待绘制列表,然后进行绘制。
生成图块最终显示
将图层分块并优先生成视口附近的图块,并交给显示器进行显示。