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

如何将Express服务端的console.log数据发送到前端实现下载进度条

实现下载进度同步的解决方案

核心思路

你当前的问题是普通HTTP请求为一次性响应模式,服务端处理请求时没有主动向客户端推送实时数据,因此前端无法拿到进度。这里直接用Server-Sent Events(SSE) 即可实现,它是HTTP原生支持的单向推送协议,无需引入WebSocket等复杂方案,完全适配你的需求场景。

第一步:修改服务端代码

调整后的Server.js代码如下,核心改动是新增SSE响应头、实时推送进度数据、处理下载完成/错误逻辑:

app.get('/', async (req, res) => {
  // 1. 设置SSE响应头,开启长连接推送
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Access-Control-Allow-Origin': '*'
  });

  fetch(`https://api.github.com/repos/${options.gitUser}/${options.gitRepo}/releases/latest`)
  .then(response => response.json())
  .then(data => {
    let zip;
    // 注意:原代码的i未声明,这里补let
    for (let i = 0; i < data['assets'].length; i++) {
      if (data['assets'][i]['name'] === `${options.softName}`) zip = data['assets'][i];
    }
    let received_bytes = 0;
    let total_bytes = 0;

    // 注意:原代码变量名和路由req重名,这里改名为downloadReq
    const downloadReq = request({
      method: 'GET',
      uri: zip['browser_download_url']
    });

    // 注意:路径反斜杠需要转义,改为双反斜杠
    const out = fs.createWriteStream(`C:\\Users\\${options.userName}\\AppData\\Roaming\\Camnor\\Camsoft\\${options.softName}`);
    downloadReq.pipe(out);

    downloadReq.on('response', data => {
      total_bytes = parseInt(data.headers['content-length']);
    });

    downloadReq.on('data', chunk => {
      received_bytes += chunk.length;
      // 2. 实时推送进度数据到前端
      res.write(`data: ${JSON.stringify({received: received_bytes, total: total_bytes})}\n\n`);
    });

    // 3. 下载完成后关闭连接
    downloadReq.on('end', () => {
      res.write(`data: ${JSON.stringify({status: 'done'})}\n\n`);
      res.end();
    });

    // 4. 处理下载错误,避免连接挂死
    downloadReq.on('error', (err) => {
      res.write(`data: ${JSON.stringify({status: 'error', msg: err.message})}\n\n`);
      res.end();
    });
  });
})

第二步:修改前端调用逻辑

替换原来的fetch逻辑,用原生EventSource监听服务端推送的进度数据即可:

Neutralino.os.execCommand('server-win.exe');
// 监听SSE推送的进度
const progressSource = new EventSource('http://localhost:3000');
progressSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.status === 'done') {
    // 下载完成,关闭连接
    progressSource.close();
    console.log('下载完成');
    return;
  }
  if (data.status === 'error') {
    console.error('下载出错:', data.msg);
    progressSource.close();
    return;
  }
  // 这里计算进度百分比,更新你的进度条UI
  const percent = ((data.received / data.total) * 100).toFixed(2);
  console.log(`当前进度:${percent}%`);
};
progressSource.onerror = (err) => {
  console.error('进度推送连接出错:', err);
  progressSource.close();
};

注意事项

  • 如果你的服务端需要同时处理多个下载任务,建议给每个下载请求加唯一标识,避免进度数据混淆
  • 生产环境可以移除Access-Control-Allow-Origin: *,改成你的前端实际访问地址,提升安全性
  • 要处理页面关闭等场景的连接断开逻辑,避免服务端产生无效长连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:45:03