在开发 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
中设置 webviewTag
为 true
。
特点:
-
功能强大:支持与嵌入内容进行深度交互。
-
不稳定性:由于官方不再推荐使用,未来可能存在兼容性问题。
-
启用方式:需要在创建 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>
,除非你正在维护一个旧项目。