Skip to content

浏览器

浏览器页面渲染过程

  1. 接收请求

    当用户在浏览器中输入网址或点击链接时,浏览器会向服务器发送一个请求,请求服务器返回该网址对应的网页内容。

  2. 服务器处理请求

    服务器收到请求后,会处理请求并返回网页内容。网页内容通常包括 HTML、CSS、JavaScript 和图片等文件。

  3. 浏览器解析 HTML

    浏览器收到服务器返回的网页内容后,会使用 HTML 解析器解析 HTML 代码,将 HTML 代码转换为文档对象模型 (DOM)。DOM 是一个树形结构,其中包含了网页的所有元素。

  4. 浏览器解析 CSS

    浏览器使用 CSS 解析器解析 CSS 代码,将 CSS 代码转换为样式规则。样式规则用于定义网页元素的样式,例如字体、颜色、大小等。

  5. 浏览器解析 JavaScript

    浏览器使用 JavaScript 解析器解析 JavaScript 代码,将 JavaScript 代码转换为可执行代码。可执行代码可以在网页中运行,实现各种功能。

  6. 浏览器构建渲染树

    浏览器将 DOM、样式规则和可执行代码组合在一起,构建一个渲染树。渲染树是一个树形结构,其中包含了网页的所有元素及其样式信息。

  7. 浏览器布局渲染树

    浏览器使用布局引擎对渲染树进行布局,计算出每个元素在网页中的位置和大小。

  8. 浏览器绘制渲染树

    浏览器使用绘制引擎将渲染树绘制到屏幕上。绘制引擎使用各种图形 API,例如 OpenGL 和 Direct3D,将元素绘制到屏幕上。

  9. 浏览器呈现网页

    浏览器将绘制好的网页呈现给用户。用户可以看到网页的内容和样式,并可以与网页中的元素进行交互。

sessionStoragelocalStoragecookie都是在浏览器中存储数据的方式,但是它们在使用期限、存储容量和与服务器的交互上有所不同。

  1. 生命周期

    • sessionStorage:仅在当前会话下有效,关闭页面或浏览器后被清除。
    • localStorage:除非被清除,否则数据永久有效。
    • cookie:可以设置过期时间。如果没有设置过期时间,那么这个 cookie 的生命周期就会结束,当关闭浏览器时,cookie 会被删除。
  2. 存储容量

    • sessionStoragelocalStorage:一般为 5MB。
    • cookie:每个 cookie 的大小一般不能超过 4KB。
  3. 与服务器的交互

    • sessionStoragelocalStorage:仅在客户端(即浏览器)中保存,不参与和服务器的通信。
    • cookie:每次都会携带在 HTTP 头中,如果使用 cookie 保存过多数据会影响到网站的性能。
  4. 作用域

    • sessionStorage:在同源的同窗口中,数据共享,即同一个窗口(或者说是 tab)的页面可以共享同一份 sessionStorage 数据,不同窗口无法共享。
    • localStorage:在同源的不同窗口中,数据共享,即不同窗口(或者说是 tab)的页面可以共享同一份 localStorage 数据。
    • cookie:cookie 是有作用域的,可以跨窗口共享。

总结来说,sessionStoragelocalStoragecookie各有其用途和特点,需要根据实际的业务需求来选择使用哪种方式来存储数据。

从输入 URL 到页面渲染的整个过程

从输入 URL 到页面渲染的整个过程,主要包括导航流程和渲染流程两大部分。

导航流程主要步骤包括:

  1. 用户输入 URL
  2. 浏览器显示 loading 状态
  3. 浏览器进程构建请求信息,通过 IPC 将 URL 请求发送给网络进程
  4. 网络进程接收到 URL 请求后,检查本地缓存,如果没有缓存,则进行网络请求,请求 DNS
  5. TCP 三次握手建立连接
  6. 数据传输过程,包括网络层在数据包上加上 IP 头部,继续向下传输到底层,目的服务器主机解析出数据部分
  7. 传输完成,TCP 四次挥手
  8. 网络进程解析获取到的数据包,根据响应头中的 Content-type 来判断响应数据的类型
  9. 渲染进程接收到“提交文档”的消息后,与网络进程建立传输数据的“管道”
  10. 浏览器收到“确认提交”的消息后,更新浏览器的页面状态,并更新 web 页面

渲染流程主要步骤包括:

  1. HTML 通过 HTML 解析器解析输出 DOM 树
  2. CSS 转换为浏览器能够理解的结构--styleSheets,进行样式计算
  3. 创建布局树,计算布局树节点的坐标位置
  4. 如果页面有复杂的效果,渲染引擎会为特定的节点生成专用的图层,并生成一棵对应的图层树
  5. 图层绘制,把一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成一个待绘制列表
  6. 将图层转换成图块
  7. 光栅化:通过进程实现图块转换成位图
  8. 浏览器进程拿到 DrawQuad 信息生成页面显示

总的来说,这个过程包括了用户输入 URL,浏览器处理请求,网络进程处理请求,数据传输,渲染进程处理文档,以及页面渲染等步骤。

跨域问题

同源策略:域名、协议、端口

解决跨域的方法:jsonp、CORS、nginx 代理跨域、nodejs 中间件代理跨域

WebSocket

由于 http 存在一个明显的弊端,即消息只能由客户端推送到服务器端,而服务器端不能主动推送到客户端,导致如果服务器如果有连续的变化,这时只能使用轮询。而轮询效率过低,并不适合,于是 WebSocket 被发明出来,相比与 http 具有以下优点:

  • 支持双向通信,实时性更强
  • 可以发送文本,也可以二进制文件
  • 协议标识符是 ws,加密后是 wss
  • 较少的控制开销。连接创建后,ws 客户端、服务端进行数据交换时,协议控制的数据包头部较小
  • 支持扩展
  • 无跨域问题
  • 实现比较简单,服务端库如 socket.io、ws,可以很好的帮助入门。客户端也只需要参照 api 实现即可

点击刷新按钮或者按 F5、按 Ctrl+F5 (强制刷新)、地址 栏回车有什么区别

  • 点击刷新按钮或者按 F5:浏览器直接对本地的缓存文件过期,但是 会带上 If-Modifed-Since,If-None-Match,这就意味着服务器会对 文件检查新鲜度,返回结果可能是 304,也有可能是 200。
  • 用户按 Ctrl+F5(强制刷新):浏览器不仅会对本地文件过期,而且 不会带上 If-Modifed-Since,If-None-Match,相当于之前从来没有 请求过,返回结果是 200。
  • 地址栏回车: 浏览器发起请求,按照正常流程,本地检查是否过期, 然后服务器检查新鲜度,最后返回内容。

渲染过程中遇到 JS 文件如何处理

JavaScript 的加载、解析与执行会阻塞文档的解析,也就是说,在构建 DOM 时,HTML 解析器若遇到了 JavaScript,那么它会暂停文档的解析,将控制权移交给 JavaScript 引擎,等 JavaScript 引擎运行完毕,浏览器再从中断的地方恢复继续解析文档。也就是说,如果想要首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。

script 标签中 defer 和 async 的区别

  • defer:延迟执行脚本,不会阻塞页面加载,适合于不影响页面加载的脚本。
  • async:异步执行脚本,会阻塞页面加载,适合于需要立即执行的脚本。

前端渲染和后端渲染的区别

前端渲染: 指的是后端返回 JSON 数据,前端利用预先写的 html 模板,循环读取 JSON 数据,拼接字符串,并插入页面。

  • 好处:网络传输数据量小。不占用服务端运算资源(解析模板),模板在前端(很有可能仅部分在前端),改结构变交互都前端自己来了,改完自己调就行。
  • 坏处:前端耗时较多。前端代码较多,因为部分以前在后台处理的交互逻辑交给了前端处理。占用少部分客户端运算资源用于解析模板。

后端渲染: 前端请求,后端用后台模板引擎直接生成 html,前端接受到数据之后,直接插入页面。

  • 好处:前端耗时少,即减少了首屏时间,模板统一在后端。前端(相对)省事,不占用客户端运算资源(解析模板),seo 比较友好
  • 坏处:占用服务器资源。

前端安全

1. XSS

1.1 概念

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

1.2 攻击类型

  • 存储型 XSS:恶意代码提交到了网站的数据库中,当用户请求数据的时候,服务器将其拼接为 HTML 后返回给了用户,从而导致了恶意代码的执行。
  • 反射型 XSS:攻击者构建了特殊的 URL,当服务器接收到请求后,从 URL 中获取数据,拼接到 HTML 后返回,从而导致了恶意代码的执行。
  • DOM 型 XSS:攻击者构建了特殊的 URL,用户打开网站后,js 脚本从 URL 中获取数据,从而导致了恶意代码的执行。

2. 如何防御 XSS

  • 使用纯前端的方式,不用服务器端拼接后返回。
  • 对需要插入到 HTML 中的代码做好充分的转义。
  • 使用 CSP。
  • 对一些敏感信息进行保护,比如 cookie 使用 http-only 。
  • 使用验证码。

3. CSRF

3.1 概念

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

3.2 攻击类型

  • GET 类型的 CSRF 攻击
  • POST 类型的 CSRF 攻击
  • 链接类型的 CSRF 攻击

4. 如何防御 CSRF

  • 同源检测的方法。
  • 使用 CSRF Token 来进行验证。
  • 使用双重 Cookie 验证的办法。
  • 使用 Samesite。

浏览器存储机制

存储机制概述特点使用场景
Web StorageHTML5 引入的存储机制,包括 localStorage 和 sessionStorage存储字符串类型的键值对,数据存在于客户端浏览器中存储非敏感应用数据,如用户偏好、临时会话数据等
Cookie用于身份验证和用户数据持久性存储在客户端浏览器中,但由服务端设置和访问会话管理、个性化、跨网站跟踪用户行为等
IndexedDB一个类似 NoSQL 的 key/value 数据库,可以存储大量结构化数据存储任何 JavaScript 类型的数据,支持数据库事务和版本控制存储用户生成的内容、应用状态、离线工作等

Web Storage

  • localStorage:用于存储持久数据,除非用户手动将其从浏览器中删除,否则数据将终身存储。
  • sessionStorage:用于存储临时会话数据,页面重新加载后仍然存在,关闭浏览器选项卡时数据丢失。

Cookie

  • 存储在客户端浏览器中,但由服务端设置和访问。
  • 用于会话管理、个性化、跨网站跟踪用户行为等。
  • 可以通过 document.cookie 来读取和设置 cookie。
  • 具有各种属性,包括 Domain、Path、Expires/Max-size、Secure、HTTPOnly 等。

IndexedDB

  • 一个类似 NoSQL 的 key/value 数据库,可以存储大量结构化数据。
  • 存储任何 JavaScript 类型的数据,支持数据库事务和版本控制。
  • 用于存储用户生成的内容、应用状态、离线工作等。
  • 使用 indexedDB.open() 来连接数据库,可以使用 onerror、onupgradeneeded、onsuccess 事件处理函数监听连接状态。

浏览器版本检测方式

可以使用 navigator.userAgent。

跨标签页通信

跨标签页通信是指在不同的浏览器标签页之间交换数据和消息。由于浏览器安全限制,直接在标签页之间通信是不可能的。因此,需要使用一些可以共享的中间介质来实现跨标签页通信。

常用方法

1. 通过父页面 window.open() 和子页面 postMessage

  • 父页面使用 window.open() 打开子页面。
  • 子页面使用 postMessage() 向父页面发送消息。
  • 父页面使用 addEventListener('message', ...) 监听子页面的消息。

2. 异步下,通过 window.open('about: blank')tab.location.href = '*'

  • 在父页面中使用 window.open('about: blank') 打开一个新标签页。
  • 在子页面中使用 tab.location.href = '*' 将标签页的 URL 设置为通配符。
  • 父页面和子页面都可以通过修改标签页的 URL 来交换数据。

3. 设置同域下共享的 localStorage 与监听 window.onstorage

  • 在同域下的不同标签页中设置共享的 localStorage 键值对。
  • 监听 window.onstorage 事件来检测 localStorage 的变化,从而实现通信。

4. 设置共享 cookie 与不断轮询脏检查 (setInterval)

  • 设置一个共享的 cookie,不同标签页都可以访问。
  • 定期使用 setInterval() 轮询 cookie 的值,从而实现通信。

5. 借助服务端或者中间层实现

  • 使用服务端或中间层作为中介,不同标签页通过服务端或中间层交换数据。

优缺点对比

方法优点缺点
window.open()postMessage安全,可靠,支持所有浏览器需要手动打开和关闭子页面
window.open('about: blank')tab.location.href = '*'异步,不需要手动打开和关闭子页面安全性较低,仅适用于异步场景
localStoragewindow.onstorage同域下共享数据,简单易用重复写入相同的值无法触发事件,受浏览器隐身模式等限制
共享 cookiesetInterval跨域通信,不需要手动打开和关闭子页面需要不断轮询,消耗性能,安全性较低
服务端或中间层安全,可靠,支持所有浏览器需要额外的服务器端或中间层支持

建议

根据具体场景选择最合适的跨标签页通信方法。对于安全性和可靠性要求较高的场景,推荐使用 window.open()postMessage 方法。对于异步场景,可以使用 window.open('about: blank')tab.location.href = '*' 方法。对于同域下简单的数据共享,可以使用 localStoragewindow.onstorage 方法。

跨域解决方案

跨域是指不同源(协议、域名、端口)的页面之间的通信。由于浏览器的同源策略,直接进行跨域通信是不允许的。因此,需要使用一些技术来解决跨域问题。

按实际使用量排序的跨域解决方案

1. CORS(跨域资源共享)

  • 服务器端设置 Access-Control-Allow-Origin 头部,指定允许跨域访问的源。
  • 客户端使用标准的 XMLHttpRequest 或 Fetch API 发起跨域请求。

2. Nginx 反向代理

  • 在服务器端使用 Nginx 作为反向代理,将跨域请求转发到目标服务器。
  • 客户端直接与 Nginx 通信,而无需直接与目标服务器通信,从而绕过同源策略。

3. WebSockets

  • 使用 WebSockets 建立持久连接,该连接不受同源策略限制。
  • 客户端和服务器可以双向发送和接收数据。

4. JSONP(JSON with Padding)

  • 客户端创建一个 <script> 元素,并将其 src 属性设置为指向目标服务器的 URL。
  • 目标服务器返回一个 JSONP 响应,其中数据被包装在一个回调函数中。
  • 客户端执行回调函数,从而获取数据。

5. Hash + iframe

  • 在客户端创建一个 iframe,并将其 src 属性设置为指向目标服务器的 URL。
  • 目标服务器通过修改 iframe 的 hash 值来传递数据。
  • 客户端通过监听 iframe 的 hashchange 事件来接收数据。

6. postMessage

  • 仅适用于具有共同祖先的窗口(例如,父窗口和子窗口)。
  • 窗口之间的通信通过 postMessage()addEventListener('message', ...) 实现。

7. document.domain

  • 仅适用于具有相同二级域名的页面。
  • 设置 document.domain 为相同的值,从而允许跨域访问。

建议

根据具体场景选择最合适的跨域解决方案。对于大多数场景,CORS 是推荐的解决方案。对于需要双向通信或持久连接的场景,可以使用 WebSockets。对于需要支持旧浏览器的场景,可以使用 JSONP 或 Hash + iframe。

Web 安全举例

XSS (跨站脚本攻击)

  • 注入恶意脚本,在受害者浏览器中执行。
  • 防范:输入验证、输出编码、CSP。

CSRF (跨站请求伪造)

  • 诱骗受害者发送恶意请求到已登录网站。
  • 防范:CSRF 令牌、同源策略、Referer 头检查。

SQL 注入

  • 注入恶意 SQL 代码,修改数据库查询。
  • 防范:预编译语句、输入验证、数据库防火墙。

命令行注入

  • 注入恶意命令,在服务器上执行。
  • 防范:输入验证、SSH、禁用不必要命令。

DDoS (分布式拒绝服务)

  • 使用僵尸网络发送大量请求,使服务器瘫痪。
  • 防范:DDoS 防护服务、限制请求速率、负载均衡。

流量劫持

  • 劫持网络流量,重定向受害者到恶意网站。
  • 防范:安全 DNS 服务、HTTPS、反钓鱼工具。

DNS 劫持

  • 修改 DNS 记录,将域名解析到恶意 IP 地址。
  • 防范:安全 DNS 服务、DNSSEC、反钓鱼工具。

HTTP 劫持

  • 劫持 HTTP 请求,修改内容或重定向受害者。
  • 防范:HTTPS、WAF、反钓鱼工具。

服务器漏洞

  • 利用服务器软件漏洞,获得服务器访问权限。
  • 防范:及时更新、限制访问、IDS。

HTTP 响应状态码分类

信息响应 (100–199)

  • 表示请求已被接收,但尚未处理。

成功响应 (200–299)

  • 表示请求已成功处理。

重定向消息 (300–399)

  • 表示客户端需要采取进一步的操作才能完成请求。

客户端错误响应 (400–499)

  • 表示客户端错误,例如无效的请求或权限不足。

服务端错误响应 (500–599)

  • 表示服务器错误,例如内部服务器错误或服务不可用。

强缓存是什么

强缓存是指浏览器在加载资源时,直接使用本地缓存中的资源,而不会再向服务器发送请求。强缓存的命中条件是:

  • 浏览器缓存中的资源具有有效的 Expires 或 Cache-Control 头部信息。
  • Expires 或 Cache-Control 头部信息中的时间尚未过期。

强缓存的优点是提高了加载速度,减少了服务器的负载。

打开 Chrome 浏览器一个 Tab 页面,至少会出现几个进程?

最新的 Chrome 浏览器至少会出现 4 个进程:

  • 1 个浏览器(Browser)主进程
  • 1 个 GPU 进程
  • 1 个网络(NetWork)进程
  • 多个渲染进程

此外,还可能会有以下进程:

  • 多个插件进程
  • iframe 进程(如果页面中有 iframe)
  • 扩展进程(如果安装了扩展)

这些进程可以通过 Chrome 任务管理器查看。