問題描述
假設我在同一個 BrowserWindow
中有兩個 BrowserView
和一個 UI 按鈕,允許用戶在顯示 bv1
或 之間切換bv2
(就像 Firefox、Chrome 等瀏覽器中的標簽"系統(tǒng),允許您在不同頁面之間切換):
Let's say I have two BrowserView
in the same BrowserWindow
and an UI button allowing the user to switch between showing bv1
or bv2
(like the "tab" system in browsers like Firefox, Chrome, that allows you to switch between the different pages):
browserWindow = new BrowserWindow({ width: 1200, height: 600 });
let bv1 = new BrowserView({ webPreferences: { nodeIntegration: false }});
bv1.setBounds({ x: 0, y: 0, width: 1200, height: 600 });
bv1.webContents.loadURL('https://www.twitter.com');
let bv2 = new BrowserView({ webPreferences: { nodeIntegration: false }});
bv2.setBounds({ x: 0, y: 0, width: 1200, height: 600 });
bv2.webContents.loadURL('https://www.twitter.com');
browserWindow.setBrowserView(bv1);
當按下按鈕(如瀏覽器中的標簽")時:
and when a button (like a "tab" in a browser) is pressed:
browserWindow.setBrowserView(bv2);
我注意到這兩個BrowserView
:
共享相同的 cookie/localStorage(我不想要!),即如果第一個連接到一個帳戶,第二個也將連接到同一個帳戶
share the same cookies/localStorage (which I don't want!), i.e. if the first is connected to an account, the second will be connected as well to the same account
重啟 Electron 應用后保留歷史記錄和 cookie(這很好,確實需要!)
keep history and cookies after restart of the Electron app (this is good and wanted indeed!)
問題:如何讓兩個 BrowserView
在 cookie/localStorage/history 方面完全隔離(因此 bv1
可以連接到一個 Twitter 帳戶并 bv2
連接到另一個)?
Question: how to have the two BrowserView
totally isolated in terms of cookies/localStorage/history (and thus bv1
could be connected to one Twitter account and bv2
to another one)?
推薦答案
所以,我設法以一種非常、非常、迂回的方式完成了這項工作.有效地劫持您自己的會話,在應用程序關閉/打開時保存和加載它.下面的代碼帶有一些注釋,前面有一些有用的鏈接.這在以開發(fā)人員身份運行以及與構建應用程序一起運行時有效.
So, I managed to get this working but in a very, very, roundabout way. Effectively session hijacking your own session, saving and loading it on app close/open. Code below with some comments, prefaced with some useful links. This worked when running as dev, and when running with a build application.
您可能需要在此處查看像這樣在本地存儲 cookie 可能存在的安全問題.
You may need to look into possible security issues here with storing cookies locally like this.
我在這個答案中唯一沒有解決的是:
The only thing I have not tackled in this answer is:
在 Electron 應用重啟后保留歷史記錄
keep history ... after restart of the Electron app
<小時>
- Electron-Json-Storage 包 - 我們使用它來存儲/檢索餅干.默認存儲位置是
C:Users\%user%AppDataRoaming\%appname%storage
. - 電子 Cookie 文檔
- Electron Session 文檔 - 特別是
session.fromPartition
文檔. - Electron-Json-Storage Package - We use this to store/retrieve cookies. The default location for storage is
C:Users\%user%AppDataRoaming\%appname%storage
. - Electron Cookies documentation
- Electron Session documentation - Notably the
session.fromPartition
docs.
const { app, BrowserWindow, BrowserView, globalShortcut, session } = require('electron');
const eJSONStorage = require('electron-json-storage');
// Our two different sesions, views, and base URL for our 'tabs'.
let bv1Session, bv2Session = session;
let bv1, bv2 = BrowserView;
const appTabUrl = 'https://www.twitter.com';
app.on('ready', () => {
const width = 1200; const height = 600;
let b1Active = true;
// Our browser window
browserWindow = new BrowserWindow({
width: width,
height: height,
});
// Our first browser window with it's own session instance.
bv1Session = session.fromPartition('persist:bv1Session', { cache: true });
bv1 = createBrowserView(appTabUrl, bv1Session, width, height);
loadCookieState('view1Cookies', bv1Session);
// Our second browser window with it's own session instance.
bv2Session = session.fromPartition('persist:bv2Session', { cache: true });
bv2 = createBrowserView(appTabUrl, bv2Session, width, height);
loadCookieState('view2Cookies', bv2Session);
// Our initial setting of the browserview
browserWindow.setBrowserView(bv1);
// Our shortcut listener and basic switch mechanic
// Set to [CTRL + /] for windows or [CMD + /] for OSX
globalShortcut.register('CommandOrControl+/', () => {
b1Active ? browserWindow.setBrowserView(bv2) : browserWindow.setBrowserView(bv1);
b1Active = !b1Active
});
});
// When the app closes, exit gracefully.
// Unregister keypress listener, save cookie states, exit the app.
app.on('window-all-closed', () => {
globalShortcut.unregisterAll();
saveCookieState('view1Cookies', bv1Session);
saveCookieState('view2Cookies', bv2Session);
app.quit();
})
// Helper method to generate a browser view.
function createBrowserView(url, session, width, height) {
let browserView = new BrowserView({
webPreferences: {
nodeIntegration: false,
nodeIntegrationInWorker: false,
session: session
}
});
browserView.setBounds({ x: 0, y: 0, width: width, height: height });
browserView.webContents.loadURL(url);
return browserView;
}
// Method that takes a session name, and our current session to save its state.
function saveCookieState(sessionName, currentSession) {
currentSession.cookies.get({}, (_, cookies) => {
cookies.forEach(cookie => {
// URL is a required paramater, take it from the domain with a little parsing.
// Twitter always uses HTTPS otherwise, we would need to check for http vs https too.
const cDomain = !cookie.domain.startsWith('.') ? `.${cookie.domain}` : cookie.domain;
cookie.url = `https://www${cDomain}`
});
// Save the set of cookies against the session name.
eJSONStorage.set(sessionName, cookies, err => {
if (err) {
throw err;
}
});
});
}
// Method that loads a session based on its name, into a session created by us.
function loadCookieState(sessionName, currentSession) {
eJSONStorage.get(sessionName, (error, cookieData) => {
// Check for empty object returned, this means no saved sessions.
if (Object.entries(cookieData).length === 0) {
return;
}
if (error) {
throw error;
}
// If we have saved sessions and no errors, load the sessions.
cookieData.forEach(cookie => currentSession.cookies.set(cookie, error => {
if (error) console.error(error);
}));
});
}
這篇關于在具有 Electron 的同一個 BrowserWindow 中有兩個隔離的(就歷史/cookies/本地存儲而言)BrowserViews的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!