Skip to content

浏览器渲染

Sep 21, 2022
巷寓
10 min read

从输入 URL 到页面呈现发生了什么

输入 URL 到页面流程
假设我们正在请求`[http://www.baidu.com](http://www.baidu.com)`这个网址

1. 构建请求

浏览器会构建请求行

javascript
// 请求方法是GET 路径为/根路径 HTTP版本为 1.1
GET / HTTP / 1.1;

2. 检查强缓存

通过 ExpiresCache-Control 头部去检查强缓存,如果命中则直接使用缓存,否则进入协商缓存

强缓存不需要发起 HTTP 请求,协商缓存需要。

协商缓存通过E-Tag + If-NO-MatchLast-Modified + If-Modified-Since两个组合从文件标志、修改时间两个方面去判断是否需要更新缓存,如果协商缓存命中,返回304 No Modified,读取缓存。

缓存位置:

  • Service Worker, 离线缓存
  • Memory Cache, 内存缓存
  • Disk Cache, 磁盘缓存
  • Push Cache,推送缓存

我是链接

3. DNS 解析

通过DNS域名解析系统(端口号53)将 URL 映射到具体的 IP 地址。

区域传输(域名数据更新时执行同步)的时候使用TCP协议,在域名解析的时候使用UDP协议

DNS 查询过程:浏览器缓存 -> 本地DNS服务器 -> 根域名服务器 -> 顶级域名服务器 -> 权威域名服务器 -> 缓存 -> 任一级命中则返回结果

DNS 解析后的 IP 会给浏览器缓存,下次访问时直接读取缓存,不需要再次解析。

4. 建立 TCP 连接

解析出 IP 地址后,根据地址和端口发起 TCP 请求。HTTP 默认端口号为80,HTTPS 默认端口号为443

Chrome 下一个域名最多只有 6 个 TCP 连接,超过则需要等待(引申下,队头阻塞问题

TCP 是面向连接的、可靠的、基于字节流的传输层协议。

TCP 通过三次握手建立客户端与服务器的连接、数据包校验保证接收方收到完整数据、四次挥手断开连接。

我是链接

响应完成后,需要判断Connection字段,如果请求头或响应头中包含Connection: Keep-Alive,表示建立了持久连接,这样TCP连接会一直保持,之后请求统一站点的资源会复用这个连接。

否则断开 TCP 连接,请求-响应流程结束。

5. 渲染

客户端拿到 html 后解析并渲染出来:

  • 构建 DOM 树:词法解析 DOM 树,由 DOM 元素及属性节点组成,根为 document
  • 构建 CSS 规则树:解析 CSS,生成 CSS 规则树
  • 构建 render 渲染树:浏览器将 DOM 树和 CSS 规则树结合,构建出渲染树
  • 布局(Layout):计算节点在屏幕的位置
  • 绘制:遍历 render 树,在 UI 后端层绘制每个节点

浏览器渲染优化

(1)JS 引入

  • 尽量将 JavaScript 文件放在 body 的最后
  • body 中间尽量不要写<script>标签
  • 通过 async/defer 优化 script 标签引入:defer 标签,顺序执行,async 标签异步执行

(2)CSS 引入

根据使用情况分 3 种模式写入:

  • link:异步加载资源,不会阻碍继续渲染
  • @import:GUI 停止渲染,在资源加载完成前会阻碍浏览器渲染
  • style: GUI 直接渲染, css 尽量放在 head 标签中会先加载,减少首次渲染时间

(3)减少回流重绘

进程与线程

Sep 21, 2022
巷寓
10 min read

一个标准的线程由线程 ID、当前指令指针(PC)、寄存器和堆栈组成。

而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成

产生死锁的原因

  • 竞争资源:竞争不可剥夺资源(一台打印机)/临时资源
  • 进程间推进顺序非法, p1 持续占用 R1,P2 持续占有 R2,P1 调用 R2 就会出现问题

浏览器安全

Sep 21, 2022
巷寓
10 min read

XSS 跨站脚本攻击

XSS 全称是 Cross Site Scripting(跨站脚本),为了和 CSS 区分,所以叫 XSS

XSS 攻击指的是浏览器中执行恶意脚本,从而获取用户信息并进行操作

  1. 窃取Cookie
  2. 监听用户行为,比如用户输入账户密码后发送至黑客服务器
  3. 修改 DOM 伪装登录表单
  4. 在页面生成浮窗广告

XSS 实现方式

通常 XSS 攻击实现方式有三种:存储型,反射型,文档型

存储型,将脚本存储到服务器数据库,然后在客户端执行。常见场景就是在留言评论区提交一段恶意脚本,若没有做转义工作就存储到了数据库,在页面渲染时直接执行

反射型,指将恶意脚本作为网络请求的一部分,没有存储到服务器数据库中。  比如下方请求,服务器拿到search参数,将内容返回给浏览器端,浏览器发现是个脚本直接执行,这样就被攻击了。

javascript
https://baidu.com?search=<script>alert("你完蛋了")</script>

文档型,不会经过服务端,而是作为中间人的角色,在数据传输过程劫持到网络数据包,然后修改里面的 html 文档!劫持方式包括 WIFI路由器劫持本地恶意软件等。

XSS 防范措施

  1. 对用户的输入进行转码或者过滤
  2. 利用 CSP。浏览器的内容安全策略,核心思想是让服务器决定客户端加载哪些资源。具体可以完成:限制其他域的资源加载; 禁止向其他域提交数据;提供上报机制,帮助及时发现 XSS 攻击。
  3. 利用 HttpOnly。设置 Cookie 的HttpOnly属性后,JavaScript 无法读取 Cookie 的值。这样可以很好的防范 XSS 攻击。

CSRF 跨站请求伪造攻击

CSRF(Cross-Site Request Forgery, 跨站请求伪造),指黑客通过诱导用户点击链接,打开黑客的网站,利用用户当前登录状态发起跨站请求

原理

进入黑客页面后,通过以下三种方式携带当前用户登录过的 cookie 信息,进行恶意操作。

  1. 自动发起 GET 请求
  2. 自动发起 POST 请求
  3. 诱导点击发送 GET 请求(一刀 999)

这就是 CSRF 的攻击原理,与XSS攻击相比,CSRF 攻击不需要将代码注入用户当前页面,而是跳转到新页面,利用服务器验证漏洞用户登录状态来模拟用户操作。

CSRF 防范措施

  1. 利用 Cookie 的 SamSite 属性

CSRF 攻击重要的一环就是发送目标站点的 cookie,利用这份 cookie 来模拟用户身份。

SamSite 可以设定三个值,StrictLaxNone

Strict 模式下,浏览器完全禁止第三方请求携带 Cookie。如 baidu.com 网站只能在 baidu.com 域名中请求才能携带 Cookie,其他网站请求不能。

Lax 模式下,相对宽松些,只能在GET 方法提交表单或者a 标签发送 GET 请求时携带 Cookie,其他情况不能。

None 模式,请求默认会带上 Cookie

  1. 验证来源站点 利用请求头的两个字段:Origin 和 Refer 其中Origin只包含域名信息,而Refer包含了具体的 URL 路径。 但这两个是可以伪造的,在 Ajax 请求中自定义请求头即可,安全性略差。
  2. CSRF Token

浏览器向服务器发起请求时,服务器生成的字符串 Token将其植入返回的页面中。

之后浏览器要发送请求,必须携带该字符串,然后服务器来验证合法性。通常第三方站点拿不到该 Token,请求会被服务器拒绝。

Drama is a song written by IU.