跳到主要内容

版本:5.X

Electron 上下文隔离

上下文隔离是什么?

Electron 上下文隔离功能将确保您的预加载脚本和 Electron 的内部逻辑运行在所加载的 webcontent 网页之外的另一个独立的上下文环境里。这对安全性很重要,因为它有助于阻止网站访问 Electron 的内部组件和您的预加载脚本可访问的高等级权限的 API 。

这意味着,实际上,您的预加载脚本访问的 window 对象并不是网站所能访问的对象。

例如,如果您在预加载脚本中设置 window.hello = 'wave' 并且启用了上下文隔离,当网站尝试访问 window.hello 对象时将返回 undefined。

注意

自 Electron 12 以来,默认情况下已启用上下文隔离,并且它是 所有应用程序推荐的安全设置。具体介绍和使用可参考 Electron 官方 说明

Electron 上下文隔离解决方案

Electron 上下文隔离开启状态下,不能直接在渲染进程引入 @rongcloud/imlib-next,应该在预加载脚本 preload.js 引入,并通过 contextBridge 模块暴露 RongIMLib 给渲染进程。具体修改方式如下:

step 1:主进程初始化

主进程初始化需将 webPreferences 中的 contextIsolation 设置为 true

// main.js
const { app, BrowserWindow } = require('electron')
const RCInit = require('@rongcloud/electron')

let rcService

app.on('ready', () => {
// 在 app 的 ready 事件通知后进行初始化
rcService = RCInit({
/**
* 【必填】Appkey , 自 5.6.0 版本起,必须填该参数
* [option]
*/
appkey: '<appkey>',
/**
* 【选填】消息数据库的存储位置,不推荐修改
* [option]
*/
dbPath: app.getPath('userData'),
/**
* 【选填】日志等级
* [option] 4 - DEBUG, 3 - INFO, 2(default) - WARN, 1 - ERROR
*/
logOutputLevel: 2,
/**
* 【选填】是否同步空的置顶会话,默认值为 `false`
* [option]
*/
enableSyncEmptyTopConversation: false
})

// 初始化 UI 窗口
const browserWin = new BrowserWindow({
webPreferences: {
// 指定预加载的 preload.js 文件,在其中引用 @rongcloud/electron-renderer
preload: '<path/to/preload.js>',
// Electron 开始上下文隔离
contextIsolation: true,
nodeIntegration: true
}
})

app.on('before-quit', () => {
// 在 app 退出时清理状态
rcService.destroy()
})
})

step 2: SDK导入

需在 preload.js 中引入 @rongcloud/electron-renderer 以及 @rongcloud/imlib-next

// preload.js
const { contextBridge } = require('electron')

require('@rongcloud/electron-renderer');

const RongIMLib = require('@rongcloud/imlib-next')

contextBridge.exposeInMainWorld('RongIMLib', RongIMLib)

step 3: 渲染进程使用

在渲染进程即可通过 window 对象访问到 RongIMLib,进行初始化 - 连接等动作

// 渲染进程 index.js

import { initRenderer } from '@rongcloud/electron-renderer/renderer';
initRenderer();

// 应用初始化,请务必保证此过程只被执行一次
const RongIMLib = window.RongIMLib

RongIMLib.init({ appkey: '<Your-App-Key>' });

// 添加事件监听
const Events = RongIMLib.Events

RongIMLib.addEventListener(Events.CONNECTING, () => {
console.log('正在连接服务器')
})

RongIMLib.addEventListener(Events.CONNECTED, () => {
console.log('已经连接到服务器')
})

RongIMLib.addEventListener(Events.MESSAGES, (evt) => {
console.log(evt.messages)
})

//建立连接
RongIMLib.connect('<Your-Token>').then(res => {
if (res.code === RongIMLib.ErrorCode.SUCCESS) {
console.log('连接成功, 连接用户 id 为: ', res.data.userId);
} else {
console.warn('连接失败, code:', res.code)
}
})