electron的webview和内嵌网页如何通信

在 Electron 的世界里,webview 标签相当于一个小盒子,里面可以装一个完整的网页,就像一个迷你浏览器。当你想和这个小盒子里的内容说话时(也就是进行通信),这里有几个方法可以帮你做到:

这里只写了两种方式,如果要是来找方案的客官。那直接看2就好。

1. 使用 preload 脚本

通过在 webview 标签中使用 preload 属性来指定一个脚本,该脚本在网页加载之前执行,但在网页的 JavaScript 环境中运行。这允许在不暴露全部 Node.js API 的情况下,向网页注入特定的 API 或者设置监听函数来实现双向通信。

bash 复制代码
<webview id="foo" src="http://example.com" preload="path/to/preload.js"></webview>

preload 脚本中,你可以使用 ipcRenderercontextBridge 来安全地暴露功能:

javascript 复制代码
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内部页面加载报错:

2.postMessage

由于webview 标签创建了一个独立的渲染进程,它和主应用的渲染进程是隔离的。因此,webview 内部的页面拥有自己的全局 window 对象,你不能直接从外部的渲染进程访问 webview 内的 window 对象。

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

1.electron的App.tsx模块发消息给webview内的页面:

ini 复制代码
  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内的页面接收:

javascript 复制代码
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

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

electron的App.tsx接收:

javascript 复制代码
  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 函数。
rust 复制代码
webview.executeJavaScript('document.getElementById("myButton").click()');
  • 获取页面信息:通过执行返回值的 JavaScript 代码,你可以获取网页中的数据,比如页面标题、选定的文本或其他 DOM 元素的属性。
javascript 复制代码
webview.executeJavaScript('document.title')
  .then(title => {
    console.log(`The page title is ${title}`);
  });
  • 网页自动化:可以用它来自动化测试网页的行为,例如自动填充表单、点击按钮等。
ini 复制代码
webview.executeJavaScript(`
  document.getElementById('username').value = 'exampleUser';
  document.getElementById('password').value = 'examplePass';
  document.getElementById('login-form').submit();
`);
相关推荐
崔庆才丨静觅1 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60612 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了2 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅2 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅3 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment3 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅3 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊3 小时前
jwt介绍
前端
爱敲代码的小鱼3 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax