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

Electron点击按钮加载EJS视图失败,提示无法加载本地资源

Electron点击按钮无法打开EJS视图的问题解决

问题重现

在Electron应用中,点击按钮尝试打开EJS视图,前端通过window.location="/whouseExit"跳转,主进程用Express配置了/whouseExit路由处理数据库查询并渲染EJS,但点击后报错:Not allowed to load local resource: file:///C:/whouseExit。

前端点击事件代码

document.getElementById('goto-exitW-button').addEventListener('click', () => {
   window.location="/whouseExit";
});

主进程main.js路由代码片段

appExpress.get("/whouseExit",(req,res) => {
 var Connection = require('tedious').Connection;
 var Request = require('tedious').Request;

  var config = {
    server: 'localhost',
    authentication: {
      type: 'default',
      options: {
        userName: 'sa',
        password: '42345243',
      },
    },
    options: {
      encrypt: false,
      database: 'cusst',
    },
  };

  const connection = new Connection(config);

  connection.connect((err) => {
    if (err) {
      console.log('Connection Failed');
      throw err;
    }

    executeStatement()
      .then((myRows) => {
        res.render('whouseExitejs.ejs', { myRows });
      })
      .catch((error) => {
        console.error(error);
      });
  });

  function executeStatement() {     // database stuff 
    ....
  }
});

核心错误原因

Electron渲染进程初始加载的是本地文件(如file:///xxx/index.html),此时使用相对路径/whouseExit会被解析为本地文件系统路径,而非向Express服务器发起HTTP请求,因此触发本地资源加载限制报错。

解决方案

方案1:直接请求Express渲染的HTTP页面

  1. 确保Express服务器已启动并监听指定端口(如3000),在main.js末尾添加:
    appExpress.listen(3000, () => {
      console.log('Express server running on http://localhost:3000');
    });
    
  2. 修改前端跳转代码,使用完整HTTP URL:
    document.getElementById('goto-exitW-button').addEventListener('click', () => {
      window.location = 'http://localhost:3000/whouseExit';
    });
    
  3. 配置Electron允许加载外部资源:
    创建BrowserWindow时,在webPreferences中调整配置(开发环境可临时关闭webSecurity,生产环境需配置contentSecurityPolicy):
    const mainWindow = new BrowserWindow({
      webPreferences: {
        webSecurity: false, // 开发环境用,生产环境替换为contentSecurityPolicy
        // 生产环境示例:
        // contentSecurityPolicy: "default-src 'self' http://localhost:3000;"
      }
    });
    

方案2:使用Electron IPC通信(推荐,符合Electron架构)

这种方式遵循主进程-渲染进程分离原则,数据库操作放在主进程,渲染进程通过IPC通知跳转。

  1. 主进程(main.js)修改:

    const { ipcMain, BrowserWindow } = require('electron');
    const path = require('path');
    
    // 监听渲染进程的跳转请求
    ipcMain.on('navigate-to-whouseExit', async (event) => {
      try {
        // 执行数据库查询(复用原有逻辑)
        const myRows = await executeStatement();
        // 创建新窗口加载Express渲染的页面,或直接在当前窗口加载
        const newWindow = new BrowserWindow({
          width: 800,
          height: 600,
          webPreferences: {
            contextIsolation: true,
            nodeIntegration: false
          }
        });
        // 加载Express渲染后的页面
        newWindow.loadURL('http://localhost:3000/whouseExit');
      } catch (err) {
        console.error(err);
        event.reply('navigate-error', '加载失败:' + err.message);
      }
    });
    
    // 封装数据库查询为异步函数
    async function executeStatement() {
      // 原有数据库操作逻辑,返回myRows
      return new Promise((resolve, reject) => {
        // 这里写具体的查询代码,成功时resolve(myRows),失败时reject(err)
      });
    }
    
    // 启动Express服务器
    appExpress.listen(3000);
    
  2. 渲染进程(前端代码)修改:

    const { ipcRenderer } = require('electron');
    
    document.getElementById('goto-exitW-button').addEventListener('click', () => {
      ipcRenderer.send('navigate-to-whouseExit');
    });
    
    // 监听主进程的错误反馈
    ipcRenderer.on('navigate-error', (event, msg) => {
      alert(msg);
    });
    

额外注意事项

  • 确认Express视图目录配置正确:
    appExpress.set('views', path.join(__dirname, 'views')); // 指定views文件夹绝对路径
    appExpress.set('view engine', 'ejs');
    
  • 数据库操作完成后要关闭连接,避免资源泄漏;
  • 生产环境不要使用webSecurity: false,需配置合法的contentSecurityPolicy限制资源加载范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 15:41:24