Electron应用中require语句执行失败问题求助
问题解决:Electron渲染进程中无法执行Node.js模块调用
你的问题核心是Electron渲染进程的安全限制,加上脚本模块类型不匹配,导致代码卡在require调用处无法继续执行。下面是具体的修复步骤:
1. 调整Electron主进程配置,开放Node.js API访问权限
Electron默认禁用渲染进程的Node.js集成并开启上下文隔离,这是安全默认设置。你需要在主进程的窗口配置里修改:
// main.js(你的Electron主进程文件) const { app, BrowserWindow } = require('electron'); const path = require('path'); function createWindow() { const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { // 允许渲染进程使用Node.js API nodeIntegration: true, // 关闭上下文隔离(简化场景下的设置,若需更高安全性可看后续可选方案) contextIsolation: false } }); mainWindow.loadFile('index.html'); } app.whenReady().then(() => { createWindow(); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); }); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });
2. 修正HTML中的脚本类型
你给script标签设置了type="module",但脚本使用的是CommonJS规范的require,二者不兼容会触发语法错误。直接移除该属性:
<!-- 修改后的index.html --> <html> <head> <title>Display Screenshot</title> </head> <body> <img id="screenshotImage" src="" alt="Screenshot"> <h1 id="test_id">No</h1> <!-- 移除type="module" --> <script src="get_screenshot.js"></script> </body> </html>
3. 修复脚本中的异步逻辑与二进制数据处理
util.promisify(childProcess.exec)返回的是Promise对象,必须用async/await处理才能正确获取结果;同时adb输出的是二进制PNG数据,需要转换为base64格式才能在页面显示:
// 修改后的get_screenshot.js const util = require('util'); const childProcess = require('child_process'); // 现在这行代码可以正常执行 document.getElementById('test_id').innerHTML = "Require passed!"; const exec = util.promisify(childProcess.exec); // 将screenshot改为async函数以支持await const screenshot = async () => { try { // 用await等待exec执行完成 const { stdout, stderr } = await exec('adb exec-out screencap -p'); if (stderr) { console.error('执行命令出错:', stderr); return; } // 把二进制stdout转换为base64字符串 const screenshotData = Buffer.from(stdout).toString('base64'); displayScreenshot(screenshotData); } catch (err) { console.error('捕获到错误:', err); } } function displayScreenshot(screenshotData) { const imageData = `data:image/png;base64,${screenshotData}`; const imgElement = document.getElementById('screenshotImage'); imgElement.src = imageData; } screenshot();
可选:更安全的预加载脚本方案(推荐)
如果需要兼顾安全性,可以保留上下文隔离,通过预加载脚本暴露所需API:
- 主进程配置调整:
webPreferences: { contextIsolation: true, // 保持开启 preload: path.join(__dirname, 'preload.js') // 指定预加载脚本路径 }
- 编写preload.js:
const { contextBridge } = require('electron'); const util = require('util'); const childProcess = require('child_process'); const exec = util.promisify(childProcess.exec); // 向渲染进程暴露安全的API contextBridge.exposeInMainWorld('electronAPI', { takeScreenshot: async () => { const { stdout, stderr } = await exec('adb exec-out screencap -p'); if (stderr) throw new Error(stderr); return Buffer.from(stdout).toString('base64'); } });
- 修改get_screenshot.js调用暴露的API:
document.getElementById('test_id').innerHTML = "Require passed!"; const screenshot = async () => { try { const screenshotData = await window.electronAPI.takeScreenshot(); displayScreenshot(screenshotData); } catch (err) { console.error(err); } } function displayScreenshot(screenshotData) { const imageData = `data:image/png;base64,${screenshotData}`; const imgElement = document.getElementById('screenshotImage'); imgElement.src = imageData; } screenshot();
内容的提问来源于stack exchange,提问作者Dominik Filyo
相关产品推荐
相关产品推荐

