发送标头后设置标头时出错 - Node.js

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了发送标头后设置标头时出错 - Node.js相关的知识,希望对你有一定的参考价值。

我正在构建一个带有nodejs的api来与客户端(android)和admin(web)进行交互。

当api启动时,它适用于管理员并且视图正确呈现但是当我将客户端连接到api时,我在服务器控制台中收到错误/警告,如:

App at port 4003
db connection opened successfully
Categroies Count:       2
Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:494:11)
    at ServerResponse.setHeader (_http_outgoing.js:501:3)
    at ServerResponse.header 
    (E:
odeCMSApp
ode_modulesexpresslib
esponse.js:767:10)
    at ServerResponse.json 
    (E:
odeCMSApp
ode_modulesexpresslib
esponse.js:264:10)
    at Categories.find.select.exec.then.data 
    (E:
odeCMSApp
outesadmin_categories.js:20:22)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
    (node:13880) UnhandledPromiseRejectionWarning: Unhandled promise 
    rejection (rejection id: 1): Error: Can't set headers after they are 
    sent.
    (node:13880) [DEP0018] DeprecationWarning: Unhandled promise rejections 
    are deprecated. In the future, promise rejections that are not handled 
    will terminate the Node.js process with
    a non-zero exit code.

这是我的api代码片段:

router.get('/', (req, res) => {

Categories.find({})
    .select('title slug image _id')
    .exec()
    .then(data => {
        if (data) {
            res.status(200)
                .json({
                    success: true,
                    count: data.length,
                    categories: data
                })
            // I understand that the problem lies here
            res.render('admin/all_categories', {
                categories: data
            });

        } else {
            res.render('all_categories', {
                categories: null
            });
        }
    })
    .catch(error => {
        console.error(error);
        res.send('Error 404');
    });

});

我明白这是因为我已经使用响应对象呈现了一个视图,并且我再次调用它来为客户端返回一些json。

我的问题是如何呈现视图并同时返回客户端的json数据而没有任何错误?谢谢。

答案

在您的代码中,如果一切顺利,您将向用户发送两个响应:

  if (data) {
    res.status(200).json({
      success: true,
      count: data.length,
      categories: data
    });

    // I understand that the problem lies here
    res.render('admin/all_categories', {
      categories: data
     });  
  }

在您执行res.json,res.send,res.redirect,res.render等调用的那一刻,您正在向用户(浏览器)发送正确的标头,因此,在您的情况下,在res.status(200)之后.json你试图发送res.render并且是不可能的,因为第一个res.json开始将结果发送给用户。我想你想用“数据”渲染all_categories所以你应该在将模板发送给用户之前在后端(编译)中渲染模板。

以上是关于发送标头后设置标头时出错 - Node.js的主要内容,如果未能解决你的问题,请参考以下文章

Node.js,Express:将标头发送到客户端后无法设置标头

Post Request express:发送到客户端后无法设置标头

标头未设置 node.js api 推送通知

使用 Expect --upload-file 标头发送 curl -> Node.js

未设置 Node.js 响应标头

在nodejs中发送标头后无法设置标头