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

Node.js/Express后端重复调用HTTP GET接口报错求助

解决重复调用FTP接口时的ERR_HTTP_HEADERS_SENT错误

问题根源

你把FTP客户端c定义成了全局变量,每次请求/files都会给这个全局实例绑定新的ready事件监听,但之前的监听并没有被移除。第一次请求后客户端调用c.end()断开连接,第二次请求调用c.connect()时,之前绑定的ready回调依然存在——当连接就绪后,所有历史绑定的ready回调都会执行,导致多次调用res.send(),触发"不能在发送响应后再设置头部"的错误。

修复方案

把FTP客户端的创建移到请求处理函数内部,让每个请求使用独立的客户端实例,彻底避免事件监听复用和连接状态冲突:

const express = require('express');
const ftp = require('ftp');

const app = express();
const port = 3000;

app.get('/files', (req, res) => {
    // 每次请求创建全新的FTP客户端实例
    const c = new ftp();

    c.on('ready', () => {
        c.list((err, list) => {
            c.end(); // 完成操作后断开FTP连接
            if (err) {
                return res.status(500).json({error: err.message});
            }
            res.setHeader("Content-Type", "application/json")
               .status(200)
               .send({data: list});            
        });
    });

    // 新增FTP连接错误监听,避免请求挂起
    c.on('error', (err) => {
        res.status(500).json({error: `FTP连接失败: ${err.message}`});
    });

    c.connect({
        host: 'xxx',
        user: 'xxx',
        password: 'xxx',
    });
});

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`);
});

额外优化说明

  • 每个请求独立创建客户端,用完即销毁,不会有事件残留和连接状态干扰的问题
  • 新增error事件监听,处理FTP连接失败的场景,避免客户端请求一直处于挂起状态
  • 增加c.list()的错误捕获,返回更合理的错误响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 19:01:09