浏览器原理

Mr.ZhaoAbout 8 min

1. 浏览器的渲染过程

1. 基本过程

  1. 解析HTML的所有标签,深度遍历生成DOM树

  2. 解析CSS,构建层叠样式表模型CSSOM树

  3. 构建Render Tree(渲染树)

    DOM和CSSOM根据一定的规则组合起来生成了Render Tree

  4. 布局(Layout)

    确定各个元素的大小、位置。浏览器使用一种流式处理的方法,只需要一次绘制操作就可以布局所有的元素

  5. 绘制(Painting)

    浏览器会遍历Render Tree渲染树,调用paint方法,将渲染树的各个节点绘制到屏幕上

2. 关于CSS、JS阻塞问题

  • CSS 加载会不会阻塞 JS 的加载?(不会)
  • CSS 加载会不会阻塞 JS 的执行?(会)
  • CSS 加载会不会阻塞 DOM 的解析?(不会)
  • CSS 加载会不会阻塞 DOM 的渲染?(会)
  • JS 加载会不会阻塞 DOM 的解析?(会)
  • JS 加载会不会阻塞 DOM 的渲染?(会)
  • JS 执行会不会阻塞 DOM 的解析?(会)
  • JS 执行会不会阻塞 DOM 的渲染?(会)

关于 css,js 的阻塞问题,都跟浏览器的渲染进程有关。而渲染进程又是多线程的

  • JS 引擎线程(单线程):负责解析 Javascript 脚本,运行代码
  • GUI 渲染线程:负责渲染浏览器界面,解析 HTML,CSS,构建 DOM Tree,CSSOM Tree 和 Render Tree,布局和绘制等

注意:GUI 渲染线程与 JS 引擎线程是互斥的,当 JS 引擎执行时 GUI 线程会被挂起,所以当 JS 加载和执行时,会阻塞住 DOM 的解析和渲染,导致白屏时间很长

DOM Tree 和 CSSOM Tree 是并行构建的,所以 CSS 加载不会阻塞 DOM 的解析;由于 Render Tree 是依赖于 DOM Tree 和 CSSOM Tree 的,因此,CSS 加载会阻塞 DOM 的渲染

GUI 渲染线程与 JS 引擎线程是互斥的,加载解析 CSS 时,JS 引擎会被挂起,所以 CSS 会阻塞 JS 的执行

  1. 如果遇到普通(sync)JavaScript脚本加载:文档解析的过程中,如果遇到JavaScript脚本,就会停止页面的解析进行下载,当脚本都执行完毕后,才会继续解析页面
  2. 如果遇到异步(async)JavaScript脚本加载:异步脚本会在HTML加载和解析完毕后执行
  3. 如果遇到设置了推迟的JavaScript脚本加载:文档解析时,遇到设置了defer的脚本,就会在后台进行下载,但是并不会阻止文档的渲染,当页面解析和渲染完毕后,会等到所有的defer脚本加载完毕并按照顺序执行完毕才会触发

defer是“渲染完再执行”:依赖于页面中的DOM元素(文档是否解析完毕),或者被其他脚本文件依赖

**async是“下载完就执行”:**并不关心页面中的DOM元素(文档是否解析完毕),并且也不会产生其他脚本需要的数据

2. XSS攻击

1. 什么是XSS攻击

XSS 攻击指的是跨站脚本攻击,是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使之在用户的浏览器上运行,从而盗取用户的信息如 cookie 等

XSS 的本质是因为网站没有对恶意代码进行过滤,与正常的代码混合在一起了,浏览器没有办法分辨哪些脚本是可信的,从而导致了恶意代码的执行

2. 攻击类型

XSS 可以分为存储型、反射型和 DOM 型:

  • 存储型指的是恶意脚本会存储在目标服务器上,当浏览器请求数据时,脚本从服务器传回并执行
    • 常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等
  • 反射型指的是攻击者诱导用户访问一个带有恶意代码的 URL 后,服务器端接收数据后处理,然后把带有恶意代码的数据发送到浏览器端,浏览器端解析这段带有 XSS 代码的数据后当做脚本执行,最终完成 XSS 攻击
    • 常见于通过 URL 传递参数的功能,如网站搜索、跳转等
  • DOM 型指的通过修改页面的 DOM 节点形成的 XSS
    • DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端JavaScript自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞

3. 防御XSS攻击

  1. 使用HTTP Only Cookie:将敏感信息存储在HTTP Only Cookie中,这样浏览器脚本无法访问或修改这些Cookie。这可以有效防止XSS攻击者窃取用户的身份验证信息
  2. Content Security Policy(CSP):通过CSP设置一系列策略(即白名单),限制页面中可以执行的内容来源,包括脚本、样式和其他资源
  3. 输入验证:要对用户输入的数据进行验证和过滤,确保只接受预期格式和合法字符。使用服务器端验证来拒绝恶意脚本或特殊字符
  4. 输出转义:对需要插入到HTML中的代码进行转义

3. CSRF攻击

1. 什么是CSRF攻击

CSRF 攻击指的是跨站请求伪造攻击,攻击者诱导用户进入一个第三方网站,然后该网站向被攻击网站发送跨站请求。如果用户在被攻击网站中保存了登录状态,那么攻击者就可以利用这个登录状态,绕过后台的用户验证,冒充用户向服务器执行一些操作

CSRF 攻击的本质是利用 cookie 会在同源请求中携带发送给服务器的特点,以此来实现用户的冒充

必要条件:

  1. 登录受信任网站A,并在本地生成Cookie。(如果用户没有登录网站A,那么网站B在诱导的时候,请求网站Aapi接口时,会提示你登录)
  2. 在不登出A的情况下,访问危险网站B(其实是利用了网站A的漏洞)

2. 攻击类型

常见的 CSRF 攻击有三种:

  • GET 类型的 CSRF 攻击,比如在网站中的一个 img 标签里构建一个请求,当用户打开这个网站的时候就会自动发起提交
  • POST 类型的 CSRF 攻击,比如构建一个表单,然后隐藏它,当用户进入页面时,自动提交这个表单
  • 链接类型的 CSRF 攻击,比如在 a 标签的 href 属性里构建一个请求,然后诱导用户去点击

3. 防御CSRF攻击

  1. token验证
  2. 进行同源检测,根据HTTP请求头中的referer信息验证
  3. 对cookie进行双重验证
  4. 在设置cookie时设置samesite,限制cookie不可能作为第三方cookie使用

4. 中间人攻击

1. 什么是中间人攻击

中间人攻击 (Man-in-the-middle attack, MITM) 是指攻击者与通讯的两端分别创建独立的联系, 并交换其所收到的数据, 使通讯的两端认为他们正在通过一个私密的连接与对方直接对话, 但事实上整个会话都被攻击者完全控制。在中间人攻击中,攻击者可以拦截通讯双方的通话并插入新的内容

2. 如何防范

  • 使用安全信道
  • 使用加密通信

5. 可能引起前端安全问题的情况

  • 跨站脚本 (Cross-Site Scripting, XSS): ⼀种代码注入方式, 为了与 CSS 区分所以被称作 XSS。早期常见于网络论坛, 起因是网站没有对用户的输入进行严格的限制, 使得攻击者可以将脚本上传到帖子让其他人浏览到有恶意脚本的页面, 其注入方式很简单包括但不限于 JavaScript / CSS / Flash 等
  • iframe的滥用: iframe中的内容是由第三方来提供的,默认情况下他们不受控制,他们可以在iframe中运行JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端用户体验
  • 跨站点请求伪造(Cross-Site Request Forgeries,CSRF): 指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击
  • 恶意第三方库: 无论是后端服务器应用还是前端应用开发,绝大多数时候都是在借助开发框架和各种类库进行快速开发,一旦第三方库被植入恶意代码很容易引起安全问题