electron IpcMain通信问题

kzipqqlq  于 2023-04-27  发布在  Electron
关注(0)|答案(1)|浏览(174)

我试图改变一个网页的src="".我的程序是两个html页面,在page1我有一个输入,当你按回车键或按钮,转到下一页(page2).所以在Page2中我放了一个webview来显示输入文本的搜索结果.为此我使用了ipcRender和ipcMain,但是通信不起作用。我有2个html文件和4个js文件:
在htmls中,我有输入和按钮,在另一个html中,webview要发送输入的文本,我有input.js:

const searchBtn = document.getElementById('searchBtn');
const textInput = document.getElementById('text-input');

textInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
    search();
}
});

searchBtn.addEventListener('click', () => {
    search();
});

function search() {
    const query = textInput.value;
    ipcRenderer.send('search', query); // Send to index.js the query, I checked it with a console.log and its working, so I think here its not the problem
};

哦,我在= require('electron');上遇到了问题,所以我编写了preload.js

contextBridge.exposeInMainWorld("app", API);

contextBridge.exposeInMainWorld('ipcRenderer', {
    send: (channel, data) => ipcRenderer.send(channel, data),
    on: (channel, func) => ipcRenderer.on(channel, (event, ...args) => func(...args)),
});

那么index.js就是接收input.js信号的人

ipcMain.on('search', (event, query) => {
  const url = `https://www.google.com/search?q=${encodeURIComponent(query)}`; // With console.log I checked that the query it's being send
  
  BrowserWindow.getFocusedWindow().loadURL('file://' + __dirname + '/searchPage.html');
  
  event.sender.send('search-results', url); // Problem!!
});

我注意到event.sender.send('search-results', url);没有将URL发送到search.js,而是应该将src:

const searchResults = document.querySelector('#searchResults'); // I checked with console.log and the webview it's being detected (<webview id="searchResults" style="position: absolute; width: 100%; height: 100%;"></webview>)

ipcRenderer.on('search-results', (event, results) => { // Here it's the problem
  if (searchResults && results) {
    searchResults.src = results;
  } else {
    console.error('Error: searchResults or results is undefined.');
  R
});

问题是ipcMain没有向search.js的ipcRenderer发送信号。我用console.log检查了search.js的results变量,但显示为undefined。我电子的开发控制台没有出现任何错误,所以我很困惑。我还尝试了webcontent,但不起作用。

编辑

我在windows11中使用最新版本的electron。
我附上我正在使用的两个HTMLS:
searchMenu.html
searchPage.html:
对于searchMenu,我使用如下侦听器:
input.js

const searchBtn = document.getElementById('searchBtn');
const textInput = document.getElementById('text-input');

textInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
    search();
}
});

searchBtn.addEventListener('click', () => {
    search();
});

function search() {
    const query = textInput.value;
    ipcRenderer.send('search', query);
};

我还在这里添加了我的webpreferences:

webPreferences: {
      nodeIntegration: true,
      enableRemoteModule: true,
      webviewTag: true,
      preload: path.join(__dirname, 'preload.js'),
      contentSecurityPolicy: "default-src 'self'",
    },

我分析了我的代码,它是这样的:

在最后一张图中,红色表示问题,数字表示操作顺序。我认为event.sender.send不工作。

envsm3lx

envsm3lx1#

EDIT:问题出在发送给回调的参数数量上

event.sender.send('search-results', resultsStack[ searchID ]);
//                 signalName       arg1

ipcRenderer.on('search-results', (event, results) => {})
//              signalName        arg1   arg2

当只发送1个参数时,需要2个参数,因此应该是

ipcRenderer.on('search-results', (results) => {})
//             signalName         arg1

我将离开的结果栈反正因为它可能是有用的
这很可能是由于在页面加载之前就已经向页面发送了信号,换句话说,在发送信号的时候DOM还没有准备好。我建议做一个基于ID搜索的系统,search.js要么拉取请求ID的结果(通过URL传递),要么,如果应用程序是单页系统,拉取最后的结果。类似这样:

// main.js
const resultsStack = { /* ID: results */ };

ipcMain.on('search', (event, query) => {
  const url = `https://www.google.com/search?q=${encodeURIComponent(query)}`;

  const searchID = "ID-" + new Date().getTime();
  resultsStack[searchID] = url;
  BrowserWindow.getFocusedWindow().loadURL('file://' + __dirname + '/searchPage.html?searchID='+ searchID);
});

ipcMain.on('pull-search', (event, searchID) => {
  if (resultsStack[ searchID ]) {
    event.sender.send('search-results', resultsStack[ searchID ]);
    delete resultsStack[ searchID ];
  } else {
    event.sender.send('search-results', { error: "Unknown ID" });
  }
});

请注意,loadURL在此处发送URL上的ID
searchPage.html中:

window.addEventListener("DOMContentLoaded", () => {
  // Get searchID from URL
  const searchID = new URLSearchParams(window.location.search).get("searchID");
  if (!searchID) return;

  const searchResults = document.querySelector('#searchResults');

  // Pull your search
  ipcRenderer.send('pull-search', searchID);
  // Wait for a response
  ipcRenderer.on('search-results', (results) => { // no event here, only results
    if (searchResults && results) {
      searchResults.src = results;
    } else {
      console.error('Error: searchResults or results is undefined.');
    }
  });
});

相关问题