浏览器相关知识
前端开发而言,浏览器就是我们所需要了解的宿主环境,不管是pc端移动端,我们的页面都是允许再浏览器当中。所以了解浏览器的知识很大程度能够理解网站运行的原理,并能高效的定位并解决问题。
从单进程到多进程的浏览器
为什么现在需要的是多线程浏览器?由于网站刚发展时都是简单的文字表格信息,通过单进程浏览器也能够很好的预览展示。随着网站的多元化丰富性,单进程已不能够满足。
当所有tabs页放在一个进程时,就会出现访问速度,浏览器健壮性,安全性等问题。若是单线程,只要有一个tab页面出错就会导致真个浏览器锁死,比如一个flash插件出错,就导致浏览器锁死。再多进程浏览器中就不会,flash插件出错只影响插件进程,浏览器进程,渲染进程,网络进程等等都还能够正常使用。
浏览器包括哪些进程呢?
- 浏览器进程:主要处理浏览器界面上的任务,比如用户输入,前进后退按钮,打开标签页,存储功能等等。
- 渲染进程:浏览器内核,主要处理html/css/js解析运行等等
- 网络进程:处理网络请求任务
- GPU进程: 起初设计为了3D渲染,后随着发展,ui界面都由GPU绘制
- 插件进程: 管理第三方插件
什么是线程?
线程是进程的最小单位,一个进程可包括多个线程。比如渲染进程中就包括一下线程: 注意:GUI渲染线程和js引擎线程是互斥的,当js引擎执行是GUI线程会被挂起(相当于冻结),GUI更新会被报错在一个队列中等到js引擎空闲时立即被执行
- GUI渲染线程:解析生成DOM&CSSOM树,计算样式生成layout树等等
- JS引擎线程:js引擎线程负责解析JavaScript脚步,运行代码
- 定时器触发线程:处理定时器任务
- 事件触发线程:用来控制事件循环
- 网络请求线程:处理网络请求
浏览器缓存
缓存是提高新能的重要一步,浏览器缓存分为两种:
- 强缓存
- 协商缓存 还有一个关键的知识点就是缓存的位置
详情见浏览器缓存
浏览器本地存储
主要分为:Cookie, WebStorage, IndexDB. 其中webStorage 分为localStorage和sessionStorage。
详情见浏览器本地存储
v8垃圾回收机制
v8垃圾回收机制,首先需要明白,浏览器数据的存储是怎样的需要理解JavaScript的内存机制。 这里有两个概念:
- 栈内存
- 堆内存
基础数据类型是通过执行上下文的形式存储在栈内存中,引用类型数据是存在堆内存中,注意的是栈内存中存储的是引用类型的地址。
栈内存的回收机制
栈内存有个ESP指针来指向目前栈的栈顶位置,当栈顶执行上下文执行完成,ESP指针下移,此时原本栈顶的数据就被删除了(因为访问不到了,若再有执行上下文入栈,会占用其位置将其覆盖掉)
堆内存的回收机制
堆内存区域分为两部分:
- 新生代:存放新创建的数据 --- 副垃圾回收器
- 老生代:存放旧引用类型数据 --- 主垃圾回收器
老生代容量大大于新生代。
新生代
新生代去分为两个区域:
- 对象区域
- 空闲区域
- 所有新创建对象都放在对象区域,空闲区域不放置数据。
- 当对象区域满之后,触发一次垃圾回收,将存活对象,放在空闲区域。当处理完成后,将对象区域数据清空。
- 再将对象区域和空闲区域对换,将空闲区域(此时存放着整理过后的数据)转换为对象区域,对象区域则成为空闲区域。
为了处理两次之后还存活的对象,新生代有个晋升政机制,将新生代两次垃圾回收还存活的对象,转移到老生代存储。
老生代
发生晋升其实不只是这一种原因:
- 已经经历过一次 Scavenge 回收(两次回收之后还存活)
- 空闲区域的内存占用超过25%。(???第一次知道这个条件,需要确认一下)
老生代垃圾回收机制:
标记-清除: 首先是标记过程阶段。标记阶段就是从一组根元素开始,递归遍历这组根元素,在这个遍历过程中,能到达的元素称为活动对象,没有到达的元素就可以判断为垃圾数据。 标记-整理:这个标记过程仍然与标记-清除算法里的是一样的,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
由于js线程是单线程的,所以在执行垃圾回收的时候,会阻塞执行js代码。如果垃圾回收时间过长可能会出现停顿时间过长,性能消耗,用户体验非常不好。所以研究出了一个增量标记算法。 增量标记:为了降低老生代的垃圾回收而造成的卡顿,V8 将标记过程分为一个个的子标记过程,同时让垃圾回收标记和 JavaScript 应用逻辑交替进行,直到标记阶段完成
详见垃圾回收机制
浏览器安全(XSS,CSRF等)
XSS(跨站脚本攻击)
脚本攻击主要的是在html页面中注入了攻击脚本(scrip) xss分为几大类:
- 存储型:攻击者将恶意脚本通过表单提交到后端并存储到数据库中,当页面加载时读取并被浏览器执行
- 反射型:通过特定url,将脚本添加在url上,后端获取解析并拼接在html中返回给浏览器,浏览器解析执行。
- DOM型:基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。黑客通过各种手段将恶意脚本注入用户的页面中,比如通过网络劫持在页面传输过程中修改 HTML 页面的内容,这种劫持类型很多,有通过 WiFi 路由器劫持的,有通过本地恶意软件来劫持的,它们的共同点是在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。
XSS危害:
- 窃取cookie等用户信息
- 监听用户行为:监听用户输入点击等行为,比如监听到用户输入银行卡号等等
- 修改DOM:比如伪造登录界面窃取用户信息(账号密码)
- 恶意广告弹窗
XSS防御:
- 前端&后端对用户输入内容做过滤和转码
- cookie设置httpOnly禁止用户通过js获取
- 充分利用CSP:浏览器中的内容安全策略,它的核心思想就是服务器决定浏览器加载哪些资源
- 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个JavaScript 文件也是无法被加载的;
- 禁止向第三方域提交数据,这样用户数据也不会外泄;
- 禁止执行内联脚本和未授权的脚本
- 还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题
详见XSS
CSRF(跨站请求伪造)
指的是黑客诱导用户打开链接访问黑客的网站,然后黑客利用用户目前的登录态,跨站发起请求。
-
自动发起get请求
<img src="https://xxx.com/info?user=hhh&count=100"> -
自动发起post请求
<form id='hacker-form' action="https://xxx.com/info" method="POST"> <input type="hidden" name="user" value="hhh" /> <input type="hidden" name="count" value="100" /> </form> <script>document.getElementById('hacker-form').submit();</script> -
诱导用户点击发送 GET 请求
<a href="https://xxx/info?user=hhh&count=100" taget="_blank">点击进入修仙世界</a>
和 XSS 不同的是,CSRF 攻击不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。
防范:
- 利用Cookie的SameSite属性
- 验证来源站点(origin&referer)
- csrf token验证
详见CSRF
从输入一个url到页面展示的过程
分三个大步骤吧:
- 网络请求:构建URL,判断缓存,dns解析,tcp3握手4挥手,http请求等等
- 解析算法:解析生成DOM,CSSOM,样式计算layoutTree
- 渲染页面:布局,分层,图层绘制,合成,栅格化,绘制
V8引擎是如何执行一段JavaScript代码的
- 将代码经过语法分析,词法分析解析成AST(抽象语法树)和执行上下文 a. 分词token(词法分析) b. 解析Parse(语法分析)
- 生成字节码:字节码就是介于 AST 和机器码之间的一种代码。但是与特定类型的机器码无关,字节码需要通过解释器将其转换为机器码后才能执行
- 执行代码
参考资料: 浏览器
注:个人学习记录