Если у вас отключено 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()
Если вы 'Если вы загружаете только локальные страницы, и эти страницы не загружают или не выполняют небезопасный динамический контент, тогда вы могли бы пересмотреть использование 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')
Хотя это определенно более многословно и с ним трудно иметь дело (и заставляет вещибыть асинхронным, поскольку передача сообщений является асинхронной), это также намного более безопасно.Пара небольших JS-оболочек вокруг postMessage
API может упростить эту работу (например, с помощью RPC-подобного механизма), но помните, что весь смысл использования contextIsolation
заключается в том, что вы не можете доверять средству визуализации,поэтому ваш скрипт предварительной загрузки не должен доверять ни одному сообщению, которое он получает через postMessage
API - вы всегда должны проверять полученное событие, чтобы убедиться, что вы ему доверяете.
Эта слайд-колода подробно описывает, почему отключение интеграции Node без использования изоляции контекста не всегда хорошая идея.