#javascript #electron
Вопрос:
Использование: Electron v15.2.0 с использованием быстрого запуска Electron
Я знаю, что это очень простая проблема, но, похоже, я не могу найти для нее решение. Вот код.
main.js:
// Get Tasks
ipcMain.on('json:get', (event, dataset) => {
// Read the JSON file
fs.readFile('./data/data.json', 'utf8', (err, jsonString) => {
// Throw error to console if there is one
if (err) {
console.log("File read failed:", err)
return
}
console.log(`JSON Data: ${jsonString}`)
// Send returned JSON data to mainWindow
mainWindow.webContents.send('tasks.return', jsonString)
})
})
preload.js:
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('ipcRenderer', ipcRenderer)
renderer.js
document.getElementById('test').addEventListener('click', () => {
ipcRenderer.send('json:get', 'tasks')
})
ipcRenderer.on('tasks.return', (event, json) => {
console.log(json)
})
Происходит то, что прослушиватель событий запускается правильно, я знаю это, потому что JSON будет выгружаться в консоль из main.js
кода, но он не запускается из renderer.js
кода. И я получаю ошибку: Uncaught TypeError: ipcRenderer.on is not a function
, но она вызывается:
ipcRenderer.on('tasks.return', (event, json) => {
console.log(json)
})
Но он не вызывается при срабатывании прослушивателя событий.
Я попытался добавить:
const electron = require('electron')
const { ipcRenderer } = electron
To renderer.js
, но затем я получаю эту ошибку: Uncaught SyntaxError: Identifier 'ipcRenderer' has already been declared
и ни одна из них не работает.
Я знаю, что мне нужно сократить область действия contextBridge и ipcRenderer в preload.js
файле, и я это сделаю, но проблема в том, что я не могу заставить приложение Electron отправлять сообщения обратно в главное окно.
Заранее спасибо!
Комментарии:
1. где
ipcRenderer
уже было объявлено? Это где-то еще в renderer.js ?2. о, подождите, средство визуализации — это скрипт, в который в этом случае вводится сценарий предварительной загрузки, верно? Кроме того, возможно, это всего лишь пример, но вы не должны предоставлять весь
ipcRenderer
объект скрипту. Это уязвимость системы безопасности (о, это может быть то, что вы имели в виду в своем последнем предложении)3. что, если вместо этого вы выполнили ipcRenderer.on внутри скрипта предварительной загрузки и просто запустили некоторый обратный вызов, который renderer.js отправляет для предварительной загрузки через новый API
4. @пушкин, ты гений! Перемещение ipcRenderer.к
preload.js
работам! Я не знаю почему, но это так, так что это уже что-то! Спасибо! И, да, я говорил о разоблаченномipcRenderer
в последнем предложении. Я просто хочу, чтобы это заработало, прежде чем я добавлю переменные, которые пойдут не так.5. Я думаю, что это хороший взлом, но мне кажется неправильным, что мы не можем найти эти ответы в
renderer.js
файле.
Ответ №1:
Я полагаю, вы видите эту проблему. ipcRenderer
не имеет on
метода, когда в (включена изоляция контекста?) средство визуализации.
Решение состоит в том, чтобы переместить ipcRenderer.on
логику внутри сценария предварительной загрузки следующим образом (пример полного кода здесь):
contextBridge.exposeInMainWorld("api", {
onResponse: (fn) => {
ipcRenderer.on("tasks.return", (event, ...args) => fn(...args));
}
});
И тогда ваш рендерер может сделать:
window.api.onResponse((json) => console.log(json));
(имейте в виду утечку памяти, для которой здесь упоминается решение)
Комментарии:
1. что вы погуглили, чтобы туда попасть? Прошлой ночью я потратил пару часов, пробуя разные варианты, и не смог прийти к этому ответу!
2. @coffeepostal Я бы рекомендовал поискать в выпусках github. Я смутно припоминал что-то подобное и провел этот поиск