typescript - 在 electron 渲染器中使用隔离世界 API
我已经使用...创建了我的 Electron 应用
create-electron-app $projDir --template=vite-typescript
在我的 BrowserWindow 的 webpreferences 中,我已经设置了
contextIsolation: true
nodeIntegration: false
我已经在 preload.ts 中定义了我想在 Renderer 上下文中使用的 API,如下所示:
const WORLD_ID: number = 1004;
const API_KEY: string = "api";
interface IApi {
myFun: <T>(...args: any) => Promise<T>;
}
const api: IApi = {
myFun: <T>(...args: any) => ipcRenderer.invoke("my-event", ...args) as Promise<T>
}
contextBridge.exposeInIsolatedWorld(
WORLD_ID, API_KEY, api
);
export { type IApi, API_KEY, WORLD_ID };
我已经为该 API 定义了一个 interface.d.ts:
import { type IApi, API_KEY } from '@/preload';
declare global {
interface Window {
[API_KEY]: IApi
}
}
文档 (https://www.electronjs.org/docs/latest/api/context-bridge) 表示我现在可以像这样使用该 API:
// Renderer (In isolated world id1004)
window.api.myFun()
- 我找不到任何关于如何在隔离世界中运行渲染器的例子(正如文档中友好提到的那样)。你能帮忙吗?
webFrame.executeInIsolatedWorld()无法工作,因为 webFrame 需要 path 模块,而该模块在渲染进程中不可用。有替代方法吗?
答案#1
据我所知,隔离世界可以用于提高安全性,适用于您希望在 Electron 应用的渲染进程中运行未知或不受信任的脚本的场景。想象一下某种插件/扩展系统,您的应用程序的终端用户可以安装并运行其他用户编写的脚本。您不希望这些扩展脚本相互干扰,或者干扰您自己信任的渲染脚本。
默认情况下,在隔离世界中执行的脚本可以访问 DOM API 和 JavaScript 内置对象。你可以使用 Electron 的 contextBridge.exposeInIsolatedWorld 让隔离脚本访问额外的 API。
例如,以下预加载脚本暴露了两个 API:
extensionAPI在主世界中可用。它提供了一个函数extension.execute,允许应用的网页前端在隔离世界1000中执行脚本。processAPI可在隔离世界1000中使用。它允许扩展脚本访问 Node.jsprocessAPI 的一个子集,特别是引擎和库版本。
// preload.ts
import { contextBridge, webFrame } from "electron";
const extensionAPI = {
execute: async (source: string): Promise<void> => {
await webFrame.executeJavaScriptInIsolatedWorld(1000, [{ code: source }]);
},
};
contextBridge.exposeInMainWorld("extension", extensionAPI);
const processAPI = {
versions: process.versions
};
contextBridge.exposeInIsolatedWorld(1000, "process", process);
现在,你的前端代码在主世界中运行,可以调用 extension.execute 来在隔离世界中执行某些脚本。例如:
extension.execute("console.log('Hello, Electron', process.versions.electron)");
这个例子有点牵强,并且可能违反了一些安全最佳实践,因为它在同一个隔离世界中运行所有扩展脚本。我希望它能说明隔离世界 API 的使用方法。
