我想使用 Electron 加载外部网页BrowserView
。它的 API 几乎与BrowserWindow
.
const currentWindow = remote.getCurrentWindow();
const view = new remote.BrowserView({
webPreferences: {
// contextIsolation: true,
partition: 'my-view-partition',
enableRemoteModule: false,
nodeIntegration: false,
preload: `${__dirname}/preload.js`,
sandbox: true,
},
});
view.setAutoResize({ width: true, height: true });
view.webContents.loadURL('http://localhost:3000');
In my preload.js
文件中,我只是将一个变量附加到全局对象。
process.once('loaded', () => {
global.baz = 'qux';
});
该应用程序运行于localhost:3000
是一个 React 应用程序,它引用如下值:
const sharedString = global.baz || 'Not found';
问题是我必须注释掉设置contextIsolation: true
创建时BrowserView
。这暴露了一个安全漏洞。
是否有可能(一种方式 - 从 Electron 到网页)将变量注入BrowserView
(or BrowserWindow
)同时仍在使用contextIsolation
使 Electron 环境与加载内容对全局环境所做的任何更改隔离?
Update:一种可能的方法是拦截网络协议,但我对此不确定????
app.on('ready', () => {
const { protocol } = session.fromPartition('my-partition')
protocol.interceptBufferProtocol('https', (req, callback) => {
if (req.uploadData) {
// How to handle file uploads?
callback()
return
}
// This is electron.net, docs: https://electronjs.org/docs/api/net
net
.request(req)
.on('response', (res) => {
const chunks = []
res.on('data', (chunk) => {
chunks.push(Buffer.from(chunk))
})
res.on('end', () => {
const blob = Buffer.concat(chunks)
const type = res.headers['content-type'] || []
if (type.includes('text/html') && blob.includes('<head>')) {
// FIXME?
const pos = blob.indexOf('<head>')
// inject contains the Buffer with the injected HTML script
callback(Buffer.concat([blob.slice(0, pos), inject, blob.slice(pos)]))
} else {
callback(blob)
}
})
})
.on('error', (err) => {
console.error('error', err)
callback()
})
.end()
})
})