Skip to content

Electron - Webview

Electron 中的 <webview> 标签允许您将“访客”内容(例如外部网页)直接嵌入到您的 Electron 应用中。这些内容被隔离在 webview 容器内,并在单独的进程中运行。这种隔离对于安全性至关重要,因为它阻止了访客内容拥有与您的应用主网页相同的权限,从而保护您的应用免受潜在恶意嵌入内容的侵害。您的应用与嵌入的访客内容之间的所有交互都是异步的。

虽然 <webview> 可用,但值得注意的是,对于许多用例而言,Electron 的 BrowserView API 提供了更灵活且通常更受青睐的方式来嵌入 Web 内容,并提供更大的控制力。对于简单的沙盒(sandbox)内容,带 sandbox 属性的标准 HTML <iframe> 也可以是一个选项。但是,本教程将按照原定范围重点介绍 <webview> 标签。

让我们通过 <webview> 演示嵌入外部网页。我们将嵌入 Electron 官方网站。首先,创建您的 main.js 文件:

const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1000,
height: 700,
webPreferences: {
// webviewTag is true by default, but explicitly setting it is good practice if needed.
// webviewTag: true,
nodeIntegration: false, // Recommended for security
contextIsolation: true // Recommended for security
}
});
mainWindow.loadFile(path.join(__dirname, 'index.html'));
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

接下来,创建将承载 <webview> 标签的 index.html 文件:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Electron Webview Example</title>
<style>
body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; display: flex; flex-direction: column; }
.controls { padding: 10px; background-color: #f0f0f0; text-align: center; }
#myWebview {
flex-grow: 1; /* Takes remaining space */
width: 100%;
border: none;
}
.indicator { font-style: italic; color: #555; }
</style>
</head>
<body>
<div class="controls">
<h2>Embedding Electron's Official Website Below</h2>
<div class="indicator"></div>
</div>
<webview id="myWebview" src="https://www.electronjs.org/" style="height: calc(100vh - 70px); width: 100%;"></webview>
<script>
document.addEventListener('DOMContentLoaded', () => {
const webview = document.getElementById('myWebview');
const indicator = document.querySelector('.indicator');
const handleLoadStart = () => {
indicator.textContent = 'Loading guest content...';
};
const handleLoadStop = () => {
indicator.textContent = 'Guest content loaded.';
};
const handleLoadFail = (event) => {
indicator.textContent = `Failed to load: ${event.errorCode} ${event.errorDescription}`;
console.error('Webview failed to load:', event);
};
webview.addEventListener('did-start-loading', handleLoadStart);
webview.addEventListener('did-stop-loading', handleLoadStop);
webview.addEventListener('did-fail-load', handleLoadFail);
// For more advanced interactions, you might need a preload script for the webview itself
// using its 'preload' attribute, e.g., <webview preload="./webview-preload.js" ...>
// This allows sandboxed communication between the host page and guest content.
});
</script>
</body>
</html>

要运行此应用程序,请在终端中导航到您的项目目录并执行:

npx electron .

应用程序窗口将打开,显示一个标题,其下方是在 webview 中加载的 Electron 官方网站。最初会显示类似“Loading guest content…”的消息,一旦网站加载完毕,消息将变为“Guest content loaded.”。

<webview> 标签会触发各种事件(例如 did-start-loading、did-stop-loading、console-message 等),您可以监听这些事件以进行更细粒度的控制和反馈。有关 <webview> 标签可用的事件和方法的完整列表,请参阅 Electron 官方文档。

由于其进程隔离,使用 <webview> 特别推荐用于嵌入第三方内容,这可以增强安全性。请始终确保您理解嵌入外部内容的安全隐患。对于对嵌入视图进行更精细的控制,请考虑使用 BrowserView。