电子“需求未定义”

noa*_*kra 5 html javascript node.js electron

我正在制作一个需要授予对文件系统(fs)模块访问权限的应用程序,但是即使nodeIntegration启用了渲染器,也会出现此错误:

Uncaught ReferenceError: require is not defined
Run Code Online (Sandbox Code Playgroud)

我可以找到的所有类似问题都有一个解决方案,要求他们打开nodeIntegration电源,但是我已经启用了它。

这是我的main.js:

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

let win;

app.on('ready', () => {
    var { width, height } = electron.screen.getPrimaryDisplay().workAreaSize;
    width = 1600;
    height = 900;
    win = new BrowserWindow({'minHeight': 850, 'minWidth': 1600, width, height, webPreferences: {
        contextIsolation: true,
        webSecurity: true,
        nodeIntegration: true
    }});
    win.setMenu(null);
    win.loadFile('index.html');
    win.webContents.openDevTools()
});

Run Code Online (Sandbox Code Playgroud)

我的index.js(<script src="index.js"></script>目前仅链接到index.html中)require("fs");已注释掉所有其他内容。

我不知道为什么即使nodeIntegration启用了需求仍然无法正常工作。

Mic*_*ley 6

当你有nodeIntegration残疾,但没有使用contextIsolation,你可以使用预加载脚本揭露它的安全版本全局对象上。(注意:您不应将整个fs模块公开到远程页面!)

这是以这种方式使用预加载脚本的示例:

// main process script
const mainWindow = new BrowserWindow({
  webPreferences: {
    contextIsolation: false,
    nodeIntegration: false,
    preload: './preload.js'
  }
})

mainWindow.loadURL('my-safe-file.html')



// preload.js
const { readFileSync } = require('fs')

// the host page will have access to `window.readConfig`,
// but not direct access to `readFileSync`
window.readConfig = function () {
  const data = readFileSync('./config.json')
  return data
}



// renderer.js
const config = window.readConfig()
Run Code Online (Sandbox Code Playgroud)

如果您仅加载本地页面,而这些页面没有加载或执行不安全的动态内容,那么您可能会重新考虑使用contextIsolation此策略。但是,如果您想继续前进contextIsolation(并且肯定有机会显示不安全的内容),则只能与预加载脚本进行通信,并通过传递消息postMessage

这是上面相同场景的一个示例,但是具有contextIsolation并使用消息传递功能。

// main process script
const mainWindow = new BrowserWindow({
  webPreferences: {
    contextIsolation: true,
    nodeIntegration: false,
    preload: './preload.js'
  }
})

mainWindow.loadURL('my-unsafe-file.html')



// preload.js
const { readFileSync } = require('fs')

const readConfig = function () {
  const data = readFileSync('./config.json')
  return data
}

window.addEventListener('message', (event) => {
  if (event.source !== window) return
  if (event.data.type === 'request') {
    window.postMessage({ type: 'response', content: readConfig() })
  }
})



// renderer.js
window.addEventListener('message', (event) => {
  if (event.source !== window) return
  if (event.data.type === 'response') {
    const config = event.data.content
  }
})
window.postMessage('request')
Run Code Online (Sandbox Code Playgroud)

虽然这绝对是更冗长且难以处理的(并且由于消息传递是异步的,所以迫使它们异步),但它也更加安全。围绕该postMessageAPI的一对小型JS包装器可以使其更易于使用(例如,通过类似RPC的机制),但是请记住,使用的全部目的contextIsolation是因为您不信任渲染器,因此您的预加载脚本不应postMessage不要相信通过API 收到的任何消息-您应始终验证收到的事件以确保您信任它。

本幻灯片详细描述了为什么不使用上下文隔离来关闭Node集成并不总是一个好主意。

  • @ford04 你是对的——我相信一个错误允许在一段时间内使用 `contextIsolation` 修改 `window`。我已经更新了我的答案,使其更加全面。 (2认同)