Electron Webview 通信:preload 脚本与 postMessage 方案解析

作者:开源拾贝

时间:2026-10-31

浏览:248

本文介绍 Electron 中 Webview 标签的两种主要通信方式。第一种通过 preload 脚本利用 contextBridge 和 ipcRenderer 实现安全的双向通信;第二种利用 postMessage 结合 executeJavaScript 在隔离的渲染进程间传递消息。文章详细解析了 executeJavaScript 在 DOM 交互、数据获取及自动化测试中的应用,并提供了 React 环境下的代码示例。

文章目录

1. 使用 preload 脚本

在 Electron 开发中,webview 标签用于嵌入独立的网页,其作用类似于一个内置的迷你浏览器。若需与嵌入页面进行交互通信,主要存在两种实现路径。本文重点介绍这两种方案,建议有具体需求的开发者直接参考第二种方法。

1. 使用 preload 脚本

通过为 webview 标签配置 preload 属性,可以指定一个在网页加载前执行但运行于网页 JavaScript 环境中的脚本。这种方式能够在不暴露完整 Node.js API 的前提下,向页面注入特定接口或监听器,从而建立双向通信通道。

<webview id="foo" src="http://example.com" preload="path/to/preload.js"></webview>

在 preload 脚本中,可借助 ipcRenderer 和 contextBridge 模块安全地暴露功能接口:

const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
    sendMessage: (message) => ipcRenderer.send('message-from-webview', message)
});
window.addEventListener('DOMContentLoaded', () => {
  // 从主进程接收消息
  ipcRenderer.on('message-to-webview', (event, data) => {
    console.log(data);
  });
});

【该方法目前遇到问题如下:】 webview内部页面加载报错:

1. 使用 preload 脚本

2. 使用 postMessage

由于 webview 标签会创建一个独立的渲染进程,其与应用主进程的渲染层是相互隔离的。这意味着 webview 内部页面拥有独立的全局 window 对象,外部渲染进程无法直接访问 webview 内的 window 对象。

调用 webviewEl.executeJavaScript 方法时,实际是在 webview 的上下文中执行 JavaScript 代码,因此可以通过注入脚本来实现交互。

(1) Electron 的 App.tsx 模块向 webview 内页面发送消息:

const handleSendMessage = () => {
    if (webview.current) {
      const message = { type: 'messageFromElectron', text: '这里是electron发送的消息:electron->view' };
      const script = `window.postMessage(${JSON.stringify(message)}, '*')`;
      webview.current.executeJavaScript(script);
    }
  };

在 webview 内的页面接收消息:

mounted(){
  const handleWebviewMessage = (event) => {
    const message = event.data;
    if (typeof message === 'object' && message !== null) {
      switch (message.type) {
        case 'messageFromElectron':
          console.info('Electron的消息', message);
          break;
        default:
          console.warn('接收到未知类型的消息', message);
      }
    }
  };
  window.addEventListener('message',handleWebviewMessage); 
},

(2)webview 内的页面发送消息给 Electron 主进程:

 sendMessageToElectron(){
      window.postMessage({ type: 'messageFromView', text: 'Hello from Vue!' }, '*');
    },

Electron 的 App.tsx 接收消息:

const handleWebviewMessage = (event) => {
    const message = event.data;
    if (typeof message === 'object' && message !== null) {
      switch (message.type) {
        case 'messageFromView':
          console.info('这里是webview的消息:webview->electron', message);
          break;
        default:
          console.warn('接收到未知类型的消息', message);
      }
    }
  };
    useEffect(() => {
    	const webviewEl = webview.current;
   		const handleDomReady = () => {
      		// 为 webview 内的 window 对象添加 message 事件监听器
      		webviewEl.executeJavaScript(`
     		 window.addEventListener('message', ${handleWebviewMessage.toString()})
    `);
    	};
    	if (webviewEl) {
      		webviewEl.addEventListener('dom-ready', handleDomReady);
   		 }
     // 清理工作
    	return () => {
      	if (webviewEl) {
        	// 移除之前添加的事件监听器,避免内存泄漏
        	webviewEl.removeEventListener('dom-ready', handleDomReady);
      	}
    	};
  	}, []);

知识科普: executeJavaScript

executeJavaScript 方法的主要作用是在浏览器环境中异步执行 JavaScript 代码。这个方法是 Electron 中 webContents 对象提供的一个功能,允许开发者在 web 页面的上下文中运行任意的 JavaScript 代码字符串。

由于我使用的是react框架的ref来引用webview组件的,因此需要通过这个引用来获取 webview 的 webContents,进而使用 executeJavaScript 方法。 使用场景: ● 与页面交互:你可以使用 executeJavaScript 来注入和执行自定义脚本,从而与网页中的 DOM 进行交互,修改网页内容,或者触发在网页中定义的 JavaScript 函数。

webview.executeJavaScript('document.getElementById("myButton").click()');

● 获取页面信息:通过执行返回值的 JavaScript 代码,你可以获取网页中的数据,比如页面标题、选定的文本或其他 DOM 元素的属性。

webview.executeJavaScript('document.title')
  .then(title => {
    console.log(`The page title is ${title}`);
  });

● 网页自动化:可以用它来自动化测试网页的行为,例如自动填充表单、点击按钮等。

webview.executeJavaScript(`
  document.getElementById('username').value = 'exampleUser';
  document.getElementById('password').value = 'examplePass';
  document.getElementById('login-form').submit();
`);

到此这篇关于electron的webview和内嵌网页通信的方法的文章就介绍到这了,更多相关electron webview通信内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章