错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法删除标头

Posted

技术标签:

【中文标题】错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法删除标头【英文标题】:Error [ERR_HTTP_HEADERS_SENT]: Cannot remove headers after they are sent to the client 【发布时间】:2020-07-12 08:30:09 【问题描述】:

我正在执行简单的 API 提取,但收到以下错误:

UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot remove headers after they are sent to the client 我不知道为什么会这样:

代码如下,还提供了错误的打印屏幕。我不确定这是否是与asynchronous behavior of nodejs 相关的问题:

var express = require('express');
var router = express.Router();
var axios = require('axios');
const NodeCache = require('node-cache');
const myCache = new NodeCache();

let hitCount = 0;

/* GET home page. */
router.get('/', function(req, res, next) 
    res.render('index',  title: 'Express' );
);


router.get('/hello', async function(req, res, next) 
    const allData = myCache.get('allData');

    if (!allData) 
        hitCount++;
        console.log(`hit $hitCount number of times`);
        try 
            const  data  = await axios.get(
                'https://api.vesselfinder.com/vesselslist?userkey=KEY'
            );
            const [ metaData, ships ] = data;
            myCache.set('allData', data, 70);
            console.log(data + 'This is the data');
            res.send(data);
         catch (error) 
            res.send(error);
            console.log(error);
        
    
    console.log('this is the data:', allData);
    res.send(allData);
);

module.exports = router;

到目前为止我为解决此错误所做的工作是:

我使用了this source,它通过对错误类型的广泛解释来广泛解释问题可能是什么。但是,了解正在发生的事情并没有什么用处。

我还找到了this useful 和this,但最后一个特别是缺少语句return 的代码中的错误。我的错误似乎与TypeError: data is not iterable 有关,但这是不可能的,因为我对所提供的订阅非常有效。

我找到的最接近的帖子是this one,它基本上说 “有时它是由于 nodejs 的异步行为而发生的。”现在我看到这发生在我身上,但我不确定在这种情况下如何解决。

为了完整起见,下面的打印屏幕中还显示了错误日志:

我能做些什么来解决这个错误?我做了很多研究,但我不确定如何处理 nodejs 的异步行为。 感谢您指出解决此问题的正确方向。

【问题讨论】:

【参考方案1】:

您收到此错误是因为您多次调用res.send()

router.get('/hello', async function(req, res, next) 
    const allData = myCache.get('allData');

    if (!allData) 
        hitCount++;
        console.log(`hit $hitCount number of times`);
        try 
            const  data  = await axios.get(
                'https://api.vesselfinder.com/vesselslist?userkey=KEY'
            );
            const [ metaData, ships ] = data;
            myCache.set('allData', data, 70);
            console.log(data + 'This is the data');
            res.send(data); // <-- FIRST TIME
         catch (error) 
            res.send(error);
            console.log(error);
        
    
    console.log('this is the data:', allData);
    res.send(allData); // <-- SECOND TIME
);

调用res.send() 将结束响应,因此您无法再次调用它。

您可以将第二个调用包装在 else 条件中,以确保只调用一个:

router.get('/hello', async function(req, res, next) 
    const allData = myCache.get('allData');

    if (!allData) 
      // ...
    
    else 
      console.log('this is the data:', allData);
      res.send(allData); // <-- SECOND TIME
    
);

【讨论】:

如果您展示了如何实际解决此问题,您的答案会更好(提示,它只需要添加 else 语句或战略性放置 return)。 嗨,史蒂夫,感谢您阅读这个问题。我需要两者的原因是因为在 API 上我每次调用有 1 分钟的限制,而我必须绕过它的唯一方法是缓存数据。所以我必须第一次res.send(data); 和第二次res.send(allData); 才能看到所有的船只。 到目前为止,如果我评论其中一个或另一个,程序将无法运行 我明白了,所以第二个是发送缓存的数据,如果你有的话。正如@jfriend00 建议的那样,您可以将第二个包装在else 块中。 @SteveHolgado,非常感谢,这正是问题所在。我花了很长时间才写好问题并提取所有信息发布,我很高兴你的问题很清楚。

以上是关于错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法删除标头的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不断收到“错误 [ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置标头”错误?

错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法删除标头

Express.js 中的新 Mongoose Schema `ERR_HTTP_HEADERS_SENT` 错误

Firebase - Node.js - Express - 错误 [ERR_HTTP_HEADERS_SENT]

错误 [ERR_HTTP_HEADERS_SENT] 在将标头发送到客户端后无法设置标头

错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头