electron中的webview、iframe、BrowserView哪个好

青禾大神
代码分享
发布于 2025-04-28
48 阅读
23 评论
2.4k 点赞
#NodeJs

在开发 Electron 应用时,有时需要将第三方 Web 内容嵌入到应用中。Electron 提供了三种主要方式来实现这一点:<iframe><webview> BrowserView。每种方式都有其独特的优势和适用场景。本文将详细介绍这三种方式,并帮助你选择最适合的方案。

一、使用 <iframe>

<iframe> 是 HTML 标准的一部分,在 Electron 中的行为与普通浏览器中完全一致。它允许你在页面中嵌入外部网页,但受限于宿主页面的 Content Security Policy (CSP)。

html 复制代码
<iframe
  src="https://www.example.com"
  sandbox="allow-scripts allow-same-origin"
  width="100%"
  height="500px"
></iframe>

特点:

  • 简单易用:与普通网页开发中的<iframe>用法相同。

  • 安全性:可以通过 sandbox 属性限制嵌入页面的功能,增强安全性。

  • 局限性:嵌入的内容受 CSP 限制,且无法直接访问 Electron 的主进程或渲染进程。

适用场景:

嵌入简单的第三方内容,如地图、视频等。
不需要与嵌入内容进行复杂交互的场景。

二、使用WebView

WebViews基于 Chromium 的 WebView,不被 Electron 明确支持。 我们不能保证WebView API 在未来版本的 Electron 中仍然可用。如果想要使用<webview>标签,您需要在BrowserWindow 的 webPreferences 中设置 webviewTagtrue

特点:

  • 功能强大:支持与嵌入内容进行深度交互。

  • 不稳定性:由于官方不再推荐使用,未来可能存在兼容性问题。

  • 启用方式:需要在创建 BrowserWindow 时显式启用 webviewTag。

js 复制代码
const { BrowserWindow } = require('electron');

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      webviewTag: true, // 启用 webview 标签
    },
  });

  win.loadFile('index.html');
};

在新版本中这个标签会发生剧烈的结构变化,可能会影响应用程序的稳定性。 考虑切换到其他选择,如 iframe 和Electron的 BrowserView,或避免嵌入式内容 设计的架构。

适用场景

  • 需要与嵌入内容进行复杂交互的旧项目。

  • 不建议在新项目中使用。

三、BrowserView

BrowserView 被用来让 BrowserWindow 嵌入更多的 web 内容。 它就像一个子窗口,除了它的位置是相对于父窗口。 这意味着可以替代webview标签。

BrowserView不是 DOM 的一部分,而是由主进程创建和控制。 它们只是现有窗口之上的另一层 Web 内容。 这意味着它们与您自己的 BrowserWindow 内容完全分离,并且它们的位置不受 DOM 或 CSS 的控制,而是通过在主进程中设置边界来控制其位置。 相反,它通过在主进程中设置界面来控制 。

BrowserViews 提供对其内容的最大控制,因为它们实现 webContents 的方式与 BrowserWindow 实现内容的方式类似。 但是,由于BrowserViews不是 DOM 的一部分,而是覆盖在它们之上,因此您必须手动管理它们的位置。管理方式也非常简单

特点:

  • 完全控制:通过 webContents API 可以实现对嵌入内容的深度控制。

  • 独立性:嵌入内容与主窗口内容完全分离,不会受 DOM 或 CSS 影响。

  • 灵活性:可以动态调整嵌入内容的位置和大小。

js 复制代码
// 在主进程中.
const { app, BrowserView, BrowserWindow } = require('electron')

app.whenReady().then(() => {
  const win = new BrowserWindow({ width: 800, height: 600 })
  const view = new BrowserView() //创建子窗口
  win.setBrowserView(view) //自窗口设置嵌入式子窗口
  view.setBounds({ x: 0, y: 0, width: 300, height: 300 }) //设置x,y坐标,窗口宽度和高度
  view.webContents.loadURL('https://www.electronjs.org') //加载页面
  //view.webContents  子窗口通过webContents可以实现最大控制
  //view.setAutoResize(options) 
  //width boolean(可选) - 如果为true,视图宽度跟随窗口变化。 默认值为 false
  //height boolean(可选) - 如果 true,视图的高度将增长和缩小 与窗口。 默认值为 false
  //horizontal boolean (可选) - 如果为 true,视图的x轴和宽度将随着窗口的大小变化等比例缩放。 默认值为 false
	//vertical boolean(可选) - 如果 true,视图的y位置和高度将增长 和收缩比例与窗口。 默认值为 false
})

总结:

在选择嵌入 Web 内容的方式时,可以根据以下建议进行选择:

方式 适用场景 优点 缺点
<iframe> 简单的第三方内容嵌入,如地图、视频等 简单易用,兼容性好 功能受限,无法深度交互
<webview> 旧项目中需要与嵌入内容进行复杂交互的场景 功能强大 不推荐使用,未来可能不兼容
BrowserView 新项目中需要高度定制化和复杂交互的场景 完全控制,灵活性高 需要手动管理位置和大小

推荐优先使用 BrowserView,因为它对新版本的 Electron 支持更好,且提供了最大的控制权限。如果你的需求较为简单,<iframe> 也是一个不错的选择。尽量避免使用 <webview>,除非你正在维护一个旧项目。

青禾大神

Vue技术专家 | 5年开发经验

专注前端技术领域,Vue生态贡献者,定期分享前沿技术文章。

评论 (128)

前端小白

这篇文章讲得太好了,解决了我很多疑惑!

资深开发者

对依赖收集部分的讲解很深入,期待更多原理分析文章!

相关推荐

Vue3组合式API最佳实践

3.2k阅读 · 86评论

Pinia状态管理深度解析

2.5k阅读 · 45评论