You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Electron中运行JavaScript?实现文本框代码执行返回结果方案

在Electron中开发自定义JS代码执行器

嘿,我来一步步教你搭建这个能执行textarea中JS代码的Electron应用!不过先敲个警钟:执行用户输入的未知代码风险极高,恶意代码可能访问系统资源、篡改文件,所以这个应用只适合在本地可控环境使用,绝对不能处理不信任的代码!

核心实现思路

我们会利用Electron的**进程间通信(IPC)**机制:

  1. 渲染进程(用户界面)获取textarea里的代码,通过安全暴露的API发送给主进程
  2. 主进程用Node.js的vm模块在隔离上下文里执行代码,避免污染主进程环境
  3. 执行结果返回给渲染进程,展示给用户

同时我们会用preload脚本安全地暴露通信接口,不开启nodeIntegration(Electron默认关闭,能大幅提升安全性)。


步骤1:初始化项目

先创建项目文件夹并初始化:

mkdir electron-js-runner && cd electron-js-runner
npm init -y
npm install electron --save-dev

然后在package.json里添加启动脚本:

"scripts": {
  "start": "electron ."
}

步骤2:编写主进程代码(main.js)

主进程负责创建应用窗口,以及处理代码执行的核心逻辑:

const { app, BrowserWindow, ipcMain } = require('electron');
const vm = require('vm');
const path = require('path');

// 创建应用窗口
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // 指定preload脚本,用于安全暴露API
      preload: path.join(__dirname, 'preload.js'),
      // 保持默认配置,关闭node集成,开启上下文隔离
      nodeIntegration: false,
      contextIsolation: true
    }
  });

  mainWindow.loadFile('index.html');
}

// 监听渲染进程的代码执行请求
ipcMain.handle('run-js-code', async (event, code) => {
  try {
    // 创建一个隔离的上下文,只暴露必要的全局对象(越少越安全)
    const isolatedContext = {
      console: console,
      setTimeout: setTimeout,
      // 按需添加允许访问的对象,比如Math、Date等
    };
    // 创建VM脚本并在隔离上下文执行
    const script = new vm.Script(code);
    const executionResult = script.runInNewContext(isolatedContext);
    
    // 返回序列化后的结果(IPC只能传递可序列化数据)
    return JSON.stringify({
      success: true,
      result: executionResult
    });
  } catch (error) {
    // 捕获执行错误并返回
    return JSON.stringify({
      success: false,
      error: error.message
    });
  }
});

// 应用启动逻辑
app.whenReady().then(() => {
  createWindow();

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

步骤3:编写preload脚本(preload.js)

这个脚本是主进程和渲染进程之间的安全桥梁,用来暴露通信API,不会直接暴露Node.js核心模块:

const { contextBridge, ipcRenderer } = require('electron');

// 向渲染进程的全局window对象暴露安全API
contextBridge.exposeInMainWorld('electronAPI', {
  runJSCode: (code) => ipcRenderer.invoke('run-js-code', code)
});

步骤4:编写渲染进程界面(index.html)

这是用户交互的界面,包含代码输入框、执行按钮和结果展示区:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Electron JS 执行器</title>
  <style>
    body {
      padding: 20px;
      font-family: Arial, sans-serif;
      display: flex;
      flex-direction: column;
      gap: 15px;
    }
    textarea {
      height: 200px;
      padding: 10px;
      font-family: monospace;
      font-size: 14px;
      border-radius: 4px;
      border: 1px solid #ddd;
    }
    button {
      padding: 10px 20px;
      font-size: 16px;
      cursor: pointer;
      background-color: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
    }
    button:hover {
      background-color: #0056b3;
    }
    #result-container {
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      min-height: 100px;
      white-space: pre-wrap;
      font-family: monospace;
    }
  </style>
</head>
<body>
  <h1>JavaScript 代码执行器</h1>
  <textarea id="code-input" placeholder="输入你的JS代码,比如:1+2 或者 console.log('Hello World')"></textarea>
  <button id="run-btn">执行代码</button>
  <div>
    <h3>执行结果:</h3>
    <div id="result-container"></div>
  </div>

  <script src="renderer.js"></script>
</body>
</html>

步骤5:编写渲染进程逻辑(renderer.js)

处理用户的点击事件,调用API执行代码并展示结果:

const runBtn = document.getElementById('run-btn');
const codeInput = document.getElementById('code-input');
const resultContainer = document.getElementById('result-container');

runBtn.addEventListener('click', async () => {
  const code = codeInput.value.trim();
  
  if (!code) {
    resultContainer.textContent = '请输入要执行的代码!';
    resultContainer.style.color = '#dc3545';
    return;
  }

  try {
    resultContainer.textContent = '正在执行...';
    resultContainer.style.color = '#6c757d';
    
    // 调用preload暴露的API执行代码
    const response = await window.electronAPI.runJSCode(code);
    const data = JSON.parse(response);

    if (data.success) {
      resultContainer.textContent = `✅ 执行成功:\n${data.result}`;
      resultContainer.style.color = '#28a745';
    } else {
      resultContainer.textContent = `❌ 执行错误:\n${data.error}`;
      resultContainer.style.color = '#dc3545';
    }
  } catch (error) {
    resultContainer.textContent = `⚠️ 通信错误:\n${error.message}`;
    resultContainer.style.color = '#ffc107';
  }
});

关键注意事项

  • 安全第一:再次强调,执行用户输入的代码非常危险,这个应用只能用于本地测试或可控场景,绝对不要对外开放。
  • 上下文隔离:我们用vm.runInNewContext创建隔离环境,只暴露必要的全局对象,尽量降低恶意代码的破坏能力。
  • 结果序列化:IPC通信只能传递可序列化的数据(比如字符串、数字、普通对象),如果执行结果是复杂对象(比如函数、Symbol),会被JSON序列化截断,你可以根据需求调整序列化逻辑。

内容的提问来源于stack exchange,提问作者Sarang S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:54:55