在electron渲染进程中调用NodeJS API

在Electron中,主进程和渲染进程是两个不同的执行上下文。主进程运行在Node.js环境中,可以访问Node.js的API和原生操作系统功能。渲染进程则运行在浏览器环境中,具有访问DOM和Web API的能力,但默认情况下无法直接访问Node.js的API。如果一定要使用,需要修改配置。

配置使用NodeJS API

渲染进程将在一个单独的沙盒环境中运行,无法直接访问 Node.js 的 API。不过可以在创建新窗口的时候,配置contextIsolationnodeIntegration选项来实现在渲染进程中直接调用Node.js的API。

const win = new BrowserWindow({
 width: 800,
 height: 600,
 webPreferences: {
   // 渲染进程将具有完整的Node.js环境
   nodeIntegration: true,
   // 禁用渲染进程的上下文隔离
   contextIsolation: false,
 },
})
win.loadFile('index.html')

启用nodeIntegration也会引入一些安全风险,因为渲染进程具有更高的权限,并且可以访问底层系统资源。因此,在使用nodeIntegration时需要谨慎处理,并遵循安全最佳实践。

禁用contextIsolation也会增加应用程序的潜在安全风险。渲染进程将具有与底层系统更紧密的交互,这可能导致潜在的安全漏洞和风险

<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>您好,世界</title>
</head>

<body>
   <h1>您好,世界!</h1>
   <script>
       // 我们可以在渲染进程中直接使用NodeJS的API
       const fs = require('fs');
       console.log(fs.readFileSync('./1.txt', 'utf-8'));
   </script>
</body>

</html>


使用 remote 模块

remote 模块是 Electron 提供的一个模块,用于在渲染进程中访问主进程的功能和 API。它提供了一种简单的方式来实现渲染进程与主进程之间的通信和交互。从Electron 9中开始,官方已经计划移除 remote 模块, 并且在Electron 14完成移除,引起目前我们默认情况下已经不能再使用该模块。如果非要使用的话,可以手动安装该模块,步骤如下:

  1. 安装 @electron/remote模块

    npm i @electron/remote
  2. 在主进程中初始化@electron/remote/main

    app.on('ready', () => {
       const win = new BrowserWindow({
           width: 800,
           height: 600,
           webPreferences: {
               nodeIntegration: true,
               contextIsolation: false,
           },
       })
       win.loadFile('index.html')
      // 初始化`@electron/remote/main
       require('@electron/remote/main').initialize()
       require("@electron/remote/main").enable(win.webContents)
    })
  3. 在渲染进程中使用它

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
       <meta charset="UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>您好,世界</title>
    </head>
    
    <body>
       <h1>您好,世界!</h1>
       <button id="btn">点我一下</button>
       <script>
           const remote = require('@electron/remote')
           let btn = document.getElementById('btn')
           btn.addEventListener('click', function () {
              // 使用主进程中才能使用的模块
               let win2 = new remote.BrowserWindow({ width: 400, height: 300 })
           })
       </script>
    </body>
    
    </html>

使用 remote 模块,渲染进程可以通过调用主进程的模块和函数来获取主进程提供的功能,它不仅仅是在渲染进程中可以使用NodeJS API 那么简单,通过它还可以使用在主进程中才能使用的模块。

注意:在 中electron >= 14.0.0,您必须使用新的enableAPI 为每个需要的WebContents单独启用远程模块:require("@electron/remote/main").enable(webContents).

在 中electron < 14.0.0,在创建窗口的时候。您必须传递enableRemoteModule配置项: { webPreferences: { enableRemoteModule: true } }

使用@electron/remote会使沙箱的效率大大降低

文档参考:https://github.com/electron/remote


微信 遇到疑问可加微信进行反映