admin管理员组文章数量:1426325
I've read through Electron's context isolation, IPC, and security docs, along with this post about using nodeIntegration, and this post about preload.js. It looks like there are a lot of different ways to acplish similar tasks and I'm not sure which is the best (safe, easy, etc.).
I know you can simply enable nodeIntegration
in renderer processes to access Node outside of the main process. Every source remended against that for the most part.
Here's where I'm confused. An example from Electron's documentation says you can do something like what's below.
preload.js
// preload with contextIsolation disabled
window.myAPI = {
doAThing: () => {}
}
renderer.js
// use the exposed API in the renderer
window.myAPI.doAThing()
preload.js has access to Node APIs so technically I could load in all Node processes and then access them in my renderers.
However, I also read about IPC.
part of main.js
ipcMain.on('set-title', (event, title) => {
const webContents = event.sender
const win = BrowserWindow.fromWebContents(webContents)
win.setTitle(title)
})
preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
setTitle: (title) => ipcRenderer.send('set-title', title)
})
renderer.js
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
const title = titleInput.value
window.electronAPI.setTitle(title)
});
For example, let's say I wanted to implement a function using an external npm module. Would I incorporate it in preload.js and call it from my renderer, or incorporate it in main.js, use ipcRenderer in preload.js with a channel for the function, and then call it from my renderer?
I've read through Electron's context isolation, IPC, and security docs, along with this post about using nodeIntegration, and this post about preload.js. It looks like there are a lot of different ways to acplish similar tasks and I'm not sure which is the best (safe, easy, etc.).
I know you can simply enable nodeIntegration
in renderer processes to access Node outside of the main process. Every source remended against that for the most part.
Here's where I'm confused. An example from Electron's documentation says you can do something like what's below.
preload.js
// preload with contextIsolation disabled
window.myAPI = {
doAThing: () => {}
}
renderer.js
// use the exposed API in the renderer
window.myAPI.doAThing()
preload.js has access to Node APIs so technically I could load in all Node processes and then access them in my renderers.
However, I also read about IPC.
part of main.js
ipcMain.on('set-title', (event, title) => {
const webContents = event.sender
const win = BrowserWindow.fromWebContents(webContents)
win.setTitle(title)
})
preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
setTitle: (title) => ipcRenderer.send('set-title', title)
})
renderer.js
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
const title = titleInput.value
window.electronAPI.setTitle(title)
});
For example, let's say I wanted to implement a function using an external npm module. Would I incorporate it in preload.js and call it from my renderer, or incorporate it in main.js, use ipcRenderer in preload.js with a channel for the function, and then call it from my renderer?
Share Improve this question asked Feb 14, 2022 at 11:27 dilanxdilanx 1432 silver badges7 bronze badges 1- Does this help stackoverflow./q/69605882/1244884 ? – custommander Commented Feb 15, 2022 at 16:43
2 Answers
Reset to default 3The code you pasted from the Context Isolation docu shows how you could use methods and modules exposed (via preload) to the renderer in earlierer versions of electron, before context isolation was set to true by default. This is however not how you should do it. With contextisolation = true
you need to use the contextbridge in you preload, because the window objects are kept isolated.
So the code you pasted from IPC is the way you should do it in 2022. I'd also keep my fingers off NodeIntegration, unless you really know what you're doing.
Concerning your last question: Generally I'd follow a least-privilege approach. The less power you give to the renderer, the safer.
I'll give you one example from my recent project.
I need to make screenshots and then save them somewhere. For that I need Browserwindow.webcontents.capturePage()
and fs.writeFile()
which are both only available to the main process. It would definitely be risky to expose the fs.writeFile method to the renderer so I'm not doing that.
Instead I keep my logic for writing the screenshots to my filesystem in the main process. However I want to initiate the Screenshots from the renderer (my UI). To expose as little as possible I only expose a function that calls the invoke method in preload's contextBridge that looks like this:
contextBridge.exposeInMainWorld("ipcRenderer", {
invokeSnap: async (optionsString: string) =>
await ipcRenderer.invoke("snap", optionsString),
});
In main I have a listener that handles the ining request:
ipcMain.handle("snap", async (_event, props: string) => {
// screenshot logic
return //sth that the renderer will receive back once the process is finished;
});
The renderer sends the the request and handles the response or errors like that:
window.ipcRenderer.invokeOpen(JSON.stringify(options))
.then(...)
.catch(...)
As a sideeffect this puts the heavy weight on the main process, which might not be desirable in bigger projects - idk. Maybe a more experienced electron developer can say more about that.
preload.js has access to Node APIs so technically I could load in all Node processes and then access them in my renderers.
This is not always true actually. If sandbox
is enabled, only a subset of Node APIs are accessible in preload. Source: (emphasis added)
preload scripts attached to sandboxed renderers will still have a polyfilled subset of Node.js APIs available
If you're using an external npm module and sandbox
is enabled (it probably should be), then you won't be able to import the npm module in your preload script and will have to use ipc and trigger it in the main process.
If sandbox
is disabled, and you can acplish everything you want from the renderer process, then I would say to just import the module in your preload and use it directly.
本文标签: javascriptnodeIntegration vs preloadjs vs IPC in ElectronStack Overflow
版权声明:本文标题:javascript - nodeIntegration vs preload.js vs IPC in Electron - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745397477a2656881.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论