使用res.json立即返回响应

时间:2015-02-17 00:45:42

标签: javascript node.js express sequelize.js

我有一个快速路由,它接受一些参数,查询数据库,然后返回一些响应。

我正在使用sequelize来查询db:

router.get('/query', function(req,res) {
    var name = req.params.name;
    var gid = req.params.gid;

    // Query the db
    models.user.find({ where: { name: name }}).then(function(user) {
        models.group.find({ where: { id: gid }}).then(function(group) {
            // if user found, return data to client
            if (user) {
                res.json({"user": user, "group": group});
            }
        });
    }).catch(function(error) {
        // catch any errors from db query
        res.status(500).json({"error":error});
    }); 


    // Return a server error for any other reason
    // This causes ERROR
    res.status(500).json({"error":"Something went wrong. Check your input."});    
});

但我一直在最后一行得到错误:

Can't set headers after they are sent

似乎最后一行总是运行,即使它找到了一个用户(应该将数据返回给客户端并完成)。

为什么找不到用户时,res.json(..)会立即返回客户端?由于标题已经设置,当最后一行运行时,它会抛出该错误。

4 个答案:

答案 0 :(得分:2)

您只需要有条件地返回错误。这一行:

res.status(500).json({"error":"Something went wrong. Check your input."});

总是被执行。这样做的原因是传递给find方法的函数仅在db响应后才在事件循环中稍后调用。这意味着当调用该回调时,您已经在响应上设置了错误。

您应该删除该行,或者决定何时返回错误,但不要每次都返回错误。

答案 1 :(得分:0)

记住javascript是异步的。

一旦你调用这个函数

models.user.find({ where: { name: name }})

执行最后一行:

res.status(500).json({"error":"Something went wrong. Check your input."});

您似乎正在尝试迎合两种情况:

  1. 来自客户的错误请求数据 - 即没有给出gid
  2. 内部服务器错误 - 即数据库错误
  3. 我建议将catch功能更改为:

    .catch(function(error) {
        // catch any errors from db query
        if (err === "Unable to connect to database") {
           return res.status(500).json({ error: "There was an internal error"})
        }
    
        res.status(400).json({"error": "Bad input, please ensure you sent all required data" });
    });
    

    阅读标准HTTP状态代码列表:

    http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

答案 2 :(得分:0)

@bhspencer所说的是对的。你必须删除最后一行。

该行可能在数据库中的任何查询之前执行。

答案 3 :(得分:-1)

您需要在

中实施return

models.user.find({ where: { name: name }}).then(function(user) { models.group.find({ where: { id: gid }}).then(function(group) { // if user found, return data to client if (user) { res.json({"user": user, "group": group}); return; } }); }).catch(function(error) { // catch any errors from db query res.status(500).json({"error":error}); return; });

实际上res.json(不会在没有return语句的情况下结束node.js代码执行的处理。