Использование последней стабильной версии Electron (29)
Пример кода взят из официальной документации:
import { app, BrowserWindow, protocol, net } from 'electron';
protocol.registerSchemesAsPrivileged([
{
scheme: 'foo',
privileges: {
bypassCSP: true,
standard: true,
secure: true,
supportFetchAPI: true,
}
}
]);
app.whenReady().then(() => {
console.info("app rdy")
protocol.handle('foo', (req) => {
console.info("yo", req.url); // <-- never executed
return new Response('bad', {
status: 400,
headers: { 'content-type': 'text/html' }
})
})
})
app.on('ready', () => {
win = new BrowserWindow({
width,
height,
x,
y,
frame: false,
closable: true,
webPreferences: {
preload: `preload.js`,
nodeIntegration: false,
nodeIntegrationInSubFrames: false,
contextIsolation: true,
},
});
win.loadURL(`foo://main.html`);
});
Итак, что нужно сделать — зарегистрировать протокол foo, затем загрузить в главное окно URL со схемой foo://. Это должно обрабатываться функцией-обработчиком foo, но это не так.
Функция никогда не запускается, и вместо этого открывается какое-то окно Windows с сообщением, что мне нужно загрузить какое-то приложение из магазина Windows, чтобы открыть файлы «foo»!? что за черт?
Итак, я провел еще несколько исследований и нашел эту функцию: app.setAsDefaultProtocolClient(protocol) которая, как я полагаю, должна сделать электронное приложение приложением по умолчанию, открывающим foo:// ссылки..
Итак, после того, как я добавил app.setAsDefaultProtocolClient('foo'), начался ад, и электронное приложение продолжало постоянно открывать новые экземпляры самого себя, пока мне не пришлось принудительно выключить компьютер, потому что он перестал отвечать на запросы.
Я предполагаю, что Electron по какой-то странной причине передает Windows любые URL-адреса, отличные от http или файлов, и не учитывает protocol.handle и/или registerSchemesAsPrivileged...
Кто-нибудь еще сталкивается с той же проблемой?
Вы используете оба app.on("ready", ...) и app.whenReady(). Что произойдет раньше? А вы регистрируете обработчик протокола в .then(...) после того, как обещание whenReady() выполнено, возможно, это тоже задерживает его? Другими словами: возможно, URL-адрес foo: загружается до регистрации обработчика?
Зачем мне регистрировать это и в Windows? Я хочу, чтобы он работал только для loadURL внутри моего приложения, а не для открытия внешних ссылок с помощью моего приложения. Причина в том, что куки не работают с локальными файлами, поэтому для этого мне нужно зарегистрировать новый протокол!





Это связано с сессиями! откуда: Официальные документы
Протокол регистрируется для конкретного объекта сеанса Electron. Если вы не укажете сеанс, ваш протокол будет применен к сеансу по умолчанию, который использует Electron. Однако если вы определите раздел или сеанс в веб-настройках вашего браузера Windows, то это окно будет использовать другой сеанс, и ваш собственный протокол не будет работать, если вы просто используете Electron.protocol.XXX.
Это работает:
import { app, BrowserWindow, protocol, session } from 'electron';
const path = require('node:path')
const url = require('url')
protocol.registerSchemesAsPrivileged([
{
scheme: 'foo',
privileges: {
bypassCSP: true,
standard: true,
secure: true,
supportFetchAPI: true,
}
}
]);
app.whenReady().then(() => {
const partition = 'persist:subdeveloper'
const ses = session.fromPartition(partition)
console.info("app rdy")
ses.protocol.handle('foo', (req) => {
console.info("yo", req.url); // <-- never executed
return new Response('bad', {
status: 400,
headers: { 'content-type': 'text/html' }
})
})
const mainWindow = new BrowserWindow({ webPreferences: { partition } });
mainWindow.loadURL(`foo://main.html`);
})
Вы зарегистрировали протокол в реестре Windows? Возможно программно, что было бы полезно, потому что многие «гражданские лица» (из-за отсутствия лучшего термина) сочтут это ошеломляющим, а некоторые из нас, ботаников, будут слишком бояться испортить реестр и уничтожить свою машину.