【问题标题】:Error: [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client, fetch error错误:[ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头,获取错误
【发布时间】:2021-07-03 20:02:39
【问题描述】:

由于 HTTP 错误,当我调用 sendPushMessages(message) 时,此代码不允许我发出 fetch 请求,但我不知道为什么。

控制台显示: 错误 [ERR_HTTP_HEADERS_SENT]: 发送到客户端后无法设置标头

此外,如果我评论: res.status(200).send({shop: shop[0]});代码仍然无法工作。

const {models} = require('../models');
const Sequelize = require('sequelize');

exports.findshop = async (req, res, next) => {

  sendPushMessages = async (message) => {
    try{
      let response = await fetch('https://exp.host/--/api/v2/push/send', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Accept-encoding': 'gzip, deflate',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(message),
      });

      let responsed = await response.json();
      console.log(responsed);
    }
    catch (error) {
      next(error);
    }
  }

  try {
      console.log(req.body.latitud)
      console.log(req.body.longitud)
      const user = req.user;
      const shops = await models.Shop.findAll({
        include:[{ model: models.Product, as: 'placements'}]
      });

      const shop = shops.filter(shp => {
        if (Math.abs(shp.latitud - req.body.latitud) <= 0.001 && Math.abs(shp.longitud - req.body.longitud) <= 0.001){
          return shp;
        }
      });

      if (shop[0] && user) {
        shop[0].placements.forEach(item => {
          if (item.dataValues.isoffer){
            const message = {
                to: user.pushtoken,
                sound: 'default',
                title: '¡Ofertón! ¡No te lo puedes perder!',
                body: item.productname + ' ' + item.price.toString() + '€',
            };
            sendPushMessages(message);
          }
        })  
        res.status(200).send({shop: shop[0]});
      } else {
        res.status(200).send({shop: null});
      }
  } catch (error) {
      next(error);
  }
};

【问题讨论】:

    标签: javascript express http-headers fetch http-error


    【解决方案1】:

    从您显示的代码(查看顶级请求处理程序也会很有用,这样我们可以看到代码的整个流程),如果sendPushMessages() 有错误,则会出现问题。它将调用next(err) 并继续在您的外循环中运行,该循环将尝试至少再发送一个响应,从而导致您收到ERR_HTTP_HEADERS_SENT 的错误消息。

    您需要在调用sendPushMessages() 时进行一些错误处理,以便在出现错误时停止循环。所以,这需要修复。解决这个问题的一种简单方法是从sendPushMessages() 中删除catch() 块,然后让拒绝传播回调用者。然后,在调用 sendPushMessages(message) 之前添加一个 await,如下所示:

    await sendPushMessages(message);
    

    因此,当sendPushMessages() 拒绝时,您将在findshop() 中点击您自己的catch 块,并且将只调用一次next(error) 而不会发送任何其他响应。

    如果您剩下的问题是为什么您在尝试访问 https://exp.host/--/api/v2/push/send' 时遇到错误,那么只有您可以分享您实际遇到的错误,我们才能提供帮助。您应该能够将console.log(error) 添加到您的catch() 处理程序中,这样您就可以记录您遇到的实际错误。在我的服务器代码中,我总是记录正在发生的实际最低级别错误,因为这通常需要调试问题发生的原因。

    【讨论】:

    • 如果我按照你说的做,就会出现如下错误:await sendPushMessages(message); ^^^^^ SyntaxError: await 仅在 Module._compile (internal/modules/cjs/loader.js:1121:27) 的 wrapSafe (internal/modules/cjs/loader.js:1071:16) 的异步函数中有效在 Object.Module._extensions..js (internal/modules/cjs/loader.js:1177:10) 另外,我无法启动服务器。
    • @AitorEncinas - 将您的 .forEach() 更改为常规的 for 循环。您将非常想放弃 .forEach() 异步代码。
    【解决方案2】:

    这是出现的错误:

    fetch 未定义 POST /位置 500 8.371 毫秒 - 32 错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头 在 ServerResponse.setHeader (_http_outgoing.js:526:11) 在 ServerResponse.header (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/express/lib/response.js:767:10) 在 ServerResponse.send (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/express/lib/response.js:170:12) 完成后(/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/express/lib/response.js:1004:10) 在 Object.exports.renderFile (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/jade/lib/index.js:374:12) 在 View.exports.__express [作为引擎] (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/jade/lib/index.js:417:11) 在 View.render (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/express/lib/view.js:135:8) 在 tryRender (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/express/lib/application.js:640:10) 在 Function.render (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/express/lib/application.js:592:3) 在 ServerResponse.render (/home/aitorencinas/Documents/Universidad/TFG/servidor/server_express/node_modules/express/lib/response.js:1008:7)

    【讨论】:

    • 所以,fetch() 本身就是一个浏览器,在 nodejs 中不可用,除非您添加一些第三方库来模拟该接口,例如 node-fetch。此外,这不应该出现在答案中(因为它不是答案)。您应该使用问题下方的“编辑”链接为您的问题添加更多信息。
    猜你喜欢
    • 2020-09-22
    • 2020-05-26
    • 2018-09-19
    • 2023-01-19
    • 2021-02-26
    • 2021-08-20
    • 2019-09-28
    • 2019-12-25
    相关资源
    最近更新 更多