电子“需求未定义”。 [英] Electron "require is not defined"

查看:56
本文介绍了电子“需求未定义”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 未捕获的ReferenceError:未定义require 

我能找到的所有类似问题都有一个解决方案,该解决方案说他们需要打开 nodeIntegration ,但是我已经启用了它。



这是我的main.js:

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

让胜利;

app.on('ready',()=> {
var {width,height} = electro.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()
});

我的index.js,在index.html中链接为 < script src = index.js>< / script> 当前仅包含 require( fs); ,我已注释掉所有其他内容。



我不知道为什么即使 nodeIntegration

解决方案

禁用 nodeIntegration 后,不使用 contextIsolation ,则可以使用预加载脚本在全局对象上公开其安全版本。 (注意:您不应将整个 fs 模块暴露给远程页面!)



下面是一个示例以这种方式使用预加载脚本:

  //主进程脚本
const mainWindow = new BrowserWindow({
webPreferences:{
contextIsolation:false,
nodeIntegration:false,
preload:'./preload.js'
}
})

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



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

//主机页面可以访问`window.readConfig`,
//但不能直接访问`readFileSync`
window.readConfig = function( ){
const data = readFileSync('./ config.json')
返回数据
}



//渲染器。 js
const config = window.readConfig()

如果仅加载本地页面,并且这些页面不会加载或执行不安全的动态内容,那么您可能重新考虑在此策略中使用 contextIsolation 。但是,如果要保持 contextIsolation (并且绝对可以显示不安全的内容,则应该这样做),您只能使用通过 postMessage



以下是上述相同情况的一个示例,但在 contextIsolation 上并使用了消息传递功能。

  //主进程脚本
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')
返回数据
}

window.addEventListener(梅萨ge’,(event)=> {
if(event.source!== window)返回
if(event.data.type ==='request'){
window.postMessage({type:'response',内容:readConfig()})
}
})



// renderer.js
window.addEventListener('message' ,(event)=> {
if(event.source!== window)返回
if(event.data.type ==='response'){
const config = event .data.content
}
})
window.postMessage('request')

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



此幻灯片详细介绍了为什么不使用上下文隔离来关闭Node集成并不总是一个好主意。 / p>

I'm making an application which I need to give access to the file system (fs) module, however even with nodeIntegration enabled the renderer gives me this error:

Uncaught ReferenceError: require is not defined

All similar problems I could find had a solution that said they needed to turn nodeIntegration on, however I already have it enabled.

This is my 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()
});

My index.js, linked in index.html as <script src="index.js"></script> currently only has require("fs"); in it, I've commented out all the other stuff.

I don't know why require still doesn't work even though nodeIntegration is enabled.

解决方案

When you have nodeIntegration disabled but aren't using contextIsolation, you could use a preload script to expose a safe version of it on the global object. (Note: you shouldn't expose the entire fs module to a remote page!)

Here's an example of using a preload script in this way:

// 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()

If you're only loading local pages, and those pages don't load or execute unsafe dynamic content then you might reconsider the use of contextIsolation for this strategy. If you want to keep contextIsolation on, however (and you definitely should if you have a chance of showing unsafe content), you can only communicate with the preload script with message passing via postMessage.

Here's an example of the same scenario above, but with contextIsolation on and using message passing.

// 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')

While this is definitely more verbose and difficult to deal with (and forces things to be async, because message passing is async), it's also much more secure. A pair of small JS wrappers around the postMessage API could make this easier to work with (e.g. via an RPC-like mechanism), but remember that the whole point of using contextIsolation is because you can't trust the renderer, so your preload script shouldn't trust just any message it gets via the postMessage API — you should always verify the event that you receive to ensure that you trust it.

This slide deck describers in detail why turning off Node integration without using context isolation is not always a good idea.

这篇关于电子“需求未定义”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆