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

Electron中mainWindow.loadURL()异步化,解决Express服务启动加载失败问题

解决Electron主窗口早于Express服务器启动导致页面加载失败的问题

方案一:等待服务器(含Mongoose)完全启动后再创建窗口

这种方案从根源避免加载失败,确保Express服务器和Mongoose数据库连接都准备就绪后,再打开Electron窗口。

步骤1:修改Express服务器文件(./app.js)

将服务器启动逻辑封装为Promise,确保Mongoose连接成功后再启动Express服务:

const express = require('express');
const mongoose = require('mongoose');
const app = express();

// 你的Express路由、中间件配置...

// 封装启动逻辑为Promise
async function startServer() {
  // 等待Mongoose连接完成
  await mongoose.connect('你的数据库连接字符串');
  console.log('Mongoose连接成功');
  
  // 启动Express并返回Promise
  return new Promise((resolve) => {
    const server = app.listen(3000, () => {
      console.log('Express服务器运行在http://localhost:3000');
      resolve(server);
    });
  });
}

// 导出启动Promise
module.exports = startServer();

步骤2:修改Electron主进程文件(index.js)

等待服务器启动完成后再创建窗口:

const {app, BrowserWindow} = require('electron');
// 导入服务器启动Promise
const serverPromise = require('./app');

let mainWindow

function createWindow () {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true
        }
    })

    mainWindow.loadURL('http://localhost:3000')

    mainWindow.on('closed', function () {
        mainWindow = null
    })
}

// 等待服务器就绪后创建窗口
app.whenReady().then(async () => {
  await serverPromise;
  createWindow();
});

app.on('resize', function(e,x,y) {
    mainWindow.setSize(x, y);
});

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

app.on('activate', function () {
    if (mainWindow === null) {
        createWindow()
    }
})

方案二:让Electron窗口自动重试加载直到成功

如果不想修改Express代码,可通过监听窗口加载失败事件,自动重试加载页面。

修改Electron主进程文件(index.js):

const {app, BrowserWindow} = require('electron');
const server = require('./app');

let mainWindow
const RETRY_INTERVAL = 1000; // 重试间隔(毫秒)

function createWindow () {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true
        }
    })

    // 定义页面加载函数
    function loadPage() {
        mainWindow.loadURL('http://localhost:3000')
    }

    loadPage();

    // 加载失败时自动重试
    mainWindow.webContents.on('did-fail-load', () => {
        setTimeout(loadPage, RETRY_INTERVAL);
    })

    mainWindow.on('closed', function () {
        mainWindow = null
    })
}

app.on('ready', createWindow)

app.on('resize', function(e,x,y) {
    mainWindow.setSize(x, y);
});

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

app.on('activate', function () {
    if (mainWindow === null) {
        createWindow()
    }
})

方案对比

  • 方案一:无冗余重试,启动逻辑更严谨,适合对服务就绪状态有严格要求的场景。
  • 方案二:实现简单,无需改动Express代码,适合快速调试或轻量场景。

内容的提问来源于stack exchange,提问作者José Ricardo Cedeño García

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:00:27