electron Uncaught(in promise)错误:无法读取未定义的属性(阅读“launch”)

von4xj4u  于 8个月前  发布在  Electron
关注(0)|答案(1)|浏览(98)

我目前正在通过构建一个简单的应用程序来学习electron.js,该应用程序可以从网站上抓取数据。但我面临着这个令人讨厌和恼火的错误。
Folder structure of my project
这是preload.js文件。

const { contextBridge } = require("electron");
const { puppeteer } = require("puppeteer");

contextBridge.exposeInMainWorld("puppeteer", {
  launch: async (options) => {
    const browser = await puppeteer.launch(options);
    return browser;
  },
  newPage: async (options) => {
    const browser = await puppeteer.launch(options).newPage();
    return browser;
  },
});

字符串
这是func.js文件(此文件包含抓取数据的主函数)

const main_link = async (url) => {
  const browser = await puppeteer.launch();
  const page = await puppeteer.newPage();
  await page.goto(url);
  // await page.screenshot({ path: "screenshot.png" });
  const content = await page.evaluate(() => {
    let problem = document.querySelectorAll(".card .text-right a");
    let links = [];
    problem.forEach((element) => {
      links.push(element.href);
    });
    return links;
  });
  await browser.close();
  console.log(content);
};

main_link("https://example.com");


有两个html文件(基本上是视图)。第一个是一个简单的表单,我只是要求一些数据,如姓名,年龄。(我刚刚学习电子)。我已经在第一个html文件中添加了一个按钮,将其连接到第二个html文件(Escrise.html)。
在第二个html文件中,我真的想使用一些来自网站的数据。所以这是我包含func.js文件的第二个文件。(punse.html)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
    <title>Choose</title>
    <script src="func.js" defer></script>
  </head>
  <body></body>
</html>


这是我在devtools中得到的错误(在应用程序(电子)内部)
Error Here
这将是伟大的,如果有人可以帮助我,我真的不知道如何写好的答案stackoverflow,我会从这一个肯定.我真的想做一个坚实的项目,但为此我将不得不学习电子.
我试图解决这个错误,但我认为我不是精通电子和后端。

niknxzdl

niknxzdl1#

出于安全原因,Electron的进程默认为sandboxed。对于预加载,这意味着你只能require一些特定的模块(强调我的):
为了允许渲染器进程与主进程通信,附加到沙箱渲染器的预加载脚本仍然会有一个可用的Node.js API的polyfilled子集。暴露了一个类似于Node的require模块的require函数,但只能导入Electron和Node内置模块的子集:[...]
如果你想使用puppeteer并保持沙箱,你必须在你的主进程上使用require,并使用IPC在你的进程之间通信:

preload.js

contextBridge.exposeInMainWorld("puppeteer", {
  launch: (options) => ipcRenderer.invoke('puppeteer:launch', options),
  newPage:(options) => ipcRenderer.invoke('puppeteer:newPage', options),
});

字符串

main.js

ipcMain.handle('puppeteer:launch', async (_event, options) => {
  const browser = await puppeteer.launch(options);
  return browser;
});

ipcMain.handle('puppeteer:newPage', async (_event, options) => {
  const browser = await puppeteer.launch(options).newPage();
  return browser;
});


如果你不关心沙盒/安全性,并希望在预加载时继续调用puppeteer,你可以在BrowserWindowwebPreferences中禁用sandbox

const mainWindow = new BrowserWindow({
  webPreferences: {
    sandbox: false,
    ...
  }
});


此外,在渲染器上,请确保尝试从window对象访问contextBridge公开的puppeteer函数:

const { puppeteer } = window;

相关问题