Electron Preload.js引入jQuery报错无法操作DOM解决方法
报错原因
TypeError: Cannot read properties of undefined(reading 'createElement') 是jQuery初始化失败导致的:jQuery运行时需要依赖渲染进程全局的window、document对象,而Electron 12及以上版本默认开启contextIsolation上下文隔离机制,preload脚本运行在独立沙箱环境中,无法直接访问渲染进程的DOM相关全局对象,直接require('jquery')时jQuery拿不到document对象,就会触发这个报错。
另外从设计规范来说,preload脚本的定位是主进程和渲染进程之间的安全通信桥,本身不适合编写DOM操作逻辑,所有DOM相关处理应该放在渲染进程侧执行。
可行方案
方案一(推荐,符合Electron安全规范)
把DOM操作逻辑迁移到渲染进程脚本中,preload仅负责通信桥接,不需要在preload里引入jQuery:
- 修改preload.js,通过官方推荐的
contextBridge把屏幕流获取能力暴露给渲染进程:
// preload.js const { ipcRenderer, contextBridge } = require('electron') contextBridge.exposeInMainWorld('desktopCapture', { onStreamReady: (handleStream, handleError) => { ipcRenderer.on('SET_SOURCE', async (_, sourceId) => { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { mandatory: { chromeMediaSource: 'desktop', chromeMediaSourceId: sourceId, minWidth: 1280, maxWidth: 1280, minHeight: 720, maxHeight: 720 } } }) handleStream(stream) } catch (e) { handleError(e) } }) } })
- 主进程原有
desktopCapturer相关逻辑不需要改动,在HTML页面中按常规方式引入jQuery后,编写渲染进程侧业务代码,这里可以无阻碍使用jQuery操作DOM:
// 渲染进程侧业务脚本,和页面DOM同上下文 const $ = window.jQuery window.desktopCapture.onStreamReady( function handleStream(stream) { // 这里直接写jQuery DOM操作逻辑即可 const video = $('<video>').attr('autoplay', true).appendTo('body')[0] video.srcObject = stream }, function handleError(e) { console.log(e) } )
方案二(仅本地测试可用,不推荐生产环境使用)
如果一定要在preload中直接引入jQuery,需要关闭Electron默认的安全隔离配置,有明确的安全风险,正式分发应用不要用:
- 修改主进程创建BrowserWindow的配置:
// 主进程创建窗口的webPreferences配置 webPreferences: { preload: path.join(__dirname, 'preload.js'), nodeIntegration: true, contextIsolation: false }
- 在preload.js中引入jQuery时手动绑定全局window对象:
// preload.js 顶部引入jQuery const $ = require('jquery')(window)
修改后就可以在preload的handleStream函数中直接使用jQuery操作DOM。
内容的提问来源于stack exchange,提问作者金红日
相关产品推荐
相关产品推荐

