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

Express实现XML转JSON时报ERR_HTTP_HEADERS_SENT错误的原因及缺陷排查

错误触发原因

ERR_HTTP_HEADERS_SENT 错误的核心触发原因是同一个HTTP请求下,你尝试向客户端发送了两次及以上的响应:

  1. 你在/json_results路由中首先调用了res.render()渲染pug模板,此时已经向客户端发送了HTML格式的响应头和内容
  2. produce_xml是异步函数,请求完成后的回调中你又调用了res.json()尝试发送JSON格式响应,第二次发送响应头时被Express拦截触发报错

同时因为produce_xml是异步逻辑,你直接将它的返回值作为json_results_in属性传入res.render时,XML请求还未完成,模板拿到的json_results_in实际是undefined,等到异步回调执行时,响应已经发送完毕。

代码存在的缺陷
  • 同一请求重复发送响应,违反HTTP协议单请求单响应的规则
  • 异步逻辑使用错误,没有等待异步请求返回结果就执行渲染操作
  • get_json.js中引入了express模块但全程未使用,属于冗余引入
  • xml2js.parseString的解析错误没有捕获传递,解析失败时会静默出错
  • 异步请求发生错误时仅打印控制台,没有给客户端返回错误响应,会导致请求超时
  • res.json()方法本身会自动序列化JS对象为JSON字符串,额外套JSON.stringify属于多余操作,会导致返回结果被二次序列化
修复方案

根据你的业务需求选择对应场景的修复代码:

场景1:该接口仅需要返回JSON数据,不需要渲染页面

main.js 路由修正

app.get('/json_results', (req, res, next) => {
    // 请提前定义url变量为你要请求的XML数据源地址
    getJson.produce_xml(url, function (err, data) {
        if (err) {
            return res.status(500).json({error: err.message});
        }
        // res.json会自动序列化对象,无需手动调用JSON.stringify
        res.json(data);
    });
});

get_json.js 修正

// 删掉冗余的express引入
var https = require('https');
/** PARSE XML TO JSON */
var parsedtext = require('xml2js').parseString;

function xmlToJson(url, callback) {
    var req = https.get(url, function(res) {
        var currentXml = '';

        res.on('data', function(chunk) {
            currentXml += chunk;
        })

        res.on('error', function(err) {
            callback(err, null);
        })

        res.on('timeout', function(err) {
            callback(err, null);
        })

        res.on('end', function() {
            // 捕获xml解析错误并传递
            parsedtext(currentXml, function(err, result) {
                if (err) return callback(err, null);
                callback(null, result);
            })
        })
    });
    // 捕获请求层面的错误,比如DNS解析失败、连接被拒绝等
    req.on('error', function(err) {
        callback(err, null);
    })
}

module.exports.produce_xml = xmlToJson

场景2:需要渲染json_results模板,将解析结果传入模板展示

main.js 路由修正

app.get('/json_results', (req, res, next) => {
    getJson.produce_xml(url, function (err, data) {
        if (err) {
            // 可根据自己的业务逻辑渲染错误页面
            return res.status(500).send('请求失败:' + err.message);
        }
        // 拿到异步结果后再执行渲染
        res.render('json_results', {
            title: 'NEWS TODAY', 
            json_results_in: data
        });
    });
});

get_json.js的修正逻辑和场景1一致。

注意:请确保代码中使用的url变量已提前定义为有效的XML数据源地址,否则会触发变量未定义错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:06:03