【问题标题】:Unable to use Node.js APIs in renderer process无法在渲染器进程中使用 Node.js API
【发布时间】:2021-06-01 22:26:22
【问题描述】:

无法在电子中使用任何电子或节点相关操作。 获取错误过程未定义。 我检查了他们指导添加节点支持的各个地方,但这已经完成所以卡在这里 我的主要应用程序代码是

const electron = require("electron");
const { app, BrowserWindow } = electron;

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: { nodeIntegration: true },
  });

  win.loadFile("index.html");
}

app.whenReady().then(createWindow);

app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.on("activate", () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

还有Index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
  </head>
  <body style="background: white">
    <h1>Hello World!</h1>
    <p>
      We are using node
      <script>
        document.write(process.versions.node);
      </script>
      , Chrome
      <script>
        document.write(process.versions.chrome);
      </script>
      , and Electron
      <script>
        document.write(process.versions.electron);
      </script>
      .
    </p>
  </body>
</html>

【问题讨论】:

  • Index.html 文件出错

标签: javascript node.js electron


【解决方案1】:

更新:下面的答案是一种解决方法。您不应禁用contextIsolation,也不应启用nodeIntegration。相反,您应该使用preload scriptcontextBridge API

Electron 12 中,contextIsolation 现在默认为true

如果您将其设置为false,您将可以在渲染器进程中访问 Node.js API

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: { 
     contextIsolation: false,
     nodeIntegration: true
    },
  });

  win.loadFile("index.html");
}

⚠️需要注意的是,不推荐这样做!

Electron 维护者更改默认值是有充分理由的。 this discussion

如果没有 contextIsolation,渲染器进程中运行的任何代码都可以很容易地进入 Electron 内部或您的预加载脚本,并执行您不希望任意网站执行的特权操作。

【讨论】:

  • @vikrantverma 只需在此处添加,出于安全原因,您可能确实希望启用contextIsolation。看答案here
【解决方案2】:

没有理由提升渲染器的权限。该页面上的任何第三方脚本都将以相同的权限运行,这绝对不是您想要的。

相反,您应该使用具有该权限的预加载脚本(即默认情况下可以使用 Node.js API)但保留contextIsolation=true(无论如何都是默认值)。如果您需要在预加载脚本和渲染器脚本之间共享数据,请使用 contextBridge

在我的示例中,我在一个相当愚蠢的命名空间 (window.BURRITO) 下将预加载脚本中的数据暴露给了渲染器脚本,以表明您在负责:

ma​​in.js

const {app, BrowserWindow} = require('electron'); //<- v13.1.7
const path = require('path');

app.whenReady().then(() => {
  const preload = path.join(__dirname, 'preload.js');
  const mainWindow = new BrowserWindow({ webPreferences: { preload }});
  mainWindow.loadFile('index.html');
});

preload.js

const {contextBridge} = require('electron');

contextBridge.exposeInMainWorld('BURRITO', {
  getNodeVer: () => process.versions.node,
  getChromeVer: () => process.versions.chrome,
  getElectronVer: () => process.versions.electron
});

renderer.js

const onClick = (sel, fn) => document.querySelector(sel).addEventListener('click', fn);
onClick('#btn1', () => alert(BURRITO.getNodeVer()));
onClick('#btn2', () => alert(BURRITO.getChromeVer()));
onClick('#btn3', () => alert(BURRITO.getElectronVer()));

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <button id="btn1">Node?</button>
    <button id="btn2">Chrome?</button>
    <button id="btn3">Electron?</button>
    <script src="./renderer.js"></script>
  </body>
</html>

【讨论】:

    猜你喜欢
    • 2017-06-01
    • 2019-12-07
    • 2017-02-06
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    相关资源
    最近更新 更多