【问题标题】:Error Setting Headers After They are Sent - Node.js发送后设置标头时出错 - Node.js
【发布时间】:2018-08-11 14:31:53
【问题描述】:

我正在用 nodejs 构建一个 api 来与客户端(android)和管理员(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:\nodeCMSApp\node_modules\express\lib\response.js:767:10)
    at ServerResponse.json 
    (E:\nodeCMSApp\node_modules\express\lib\response.js:264:10)
    at Categories.find.select.exec.then.data 
    (E:\nodeCMSApp\routes\admin_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 代码 sn-p:

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 数据而不会出现任何错误? 谢谢。

【问题讨论】:

    标签: json node.js promise response ejs


    【解决方案1】:

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

      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,因此您应该在将模板发送给用户之前在后端(编译)中渲染模板。

    【讨论】:

    • 我不明白你的建议。这是后端,客户端是移动设备。这就是为什么我在渲染视图的同时返回了 json
    • 但这是错误的,您不能执行多个发送操作。在第一个 res.status.json 标头被发送到移动设备(内容类型、内容长度等),所以第二个将失败,因为有新的标头,你不能覆盖以前发送的。
    • 好的。谢谢你的解释。
    猜你喜欢
    • 2015-05-21
    • 1970-01-01
    • 2011-10-17
    • 2018-03-13
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    相关资源
    最近更新 更多