我可以使用 res.send(foo) 两次吗?

not*_*ich 2 javascript node.js express

我想将我的令牌和用户角色发送到我的login.component.ts。

当我试图找到问题时,在我的研究中我发现有人建议使用

res.write(foo1)
res.write(foo2)
res.end
Run Code Online (Sandbox Code Playgroud)

代替

res.send(foo1)
res.send(foo2)
Run Code Online (Sandbox Code Playgroud)

但这没有用。然后我尝试用它来测试它:

res.write(foo1)
res.end()
Run Code Online (Sandbox Code Playgroud)

但这给了我一个错误:

events.js:174

  throw er; // Unhandled 'error' event
  ^

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer. Received type object
    at write_ (_http_outgoing.js:595:11)
    at ServerResponse.write (_http_outgoing.js:567:10)
    at User.findOne (C:\Users\notan\GitHub\se3316-notansandwich-lab5\server\controllers\user.controller.js:46:33)
    at C:\Users\notan\node_modules\mongoose\lib\model.js:4604:16
    at C:\Users\notan\node_modules\mongoose\lib\query.js:4348:12
    at process.nextTick (C:\Users\notan\node_modules\mongoose\lib\query.js:2850:28)
    at process._tickCallback (internal/process/next_tick.js:61:11)
Emitted 'error' event at:
    at C:\Users\notan\node_modules\mongoose\lib\model.js:4606:13
    at C:\Users\notan\node_modules\mongoose\lib\query.js:4348:12
    at process.nextTick (C:\Users\notan\node_modules\mongoose\lib\query.js:2850:28)
    at process._tickCallback (internal/process/next_tick.js:61:11)
Run Code Online (Sandbox Code Playgroud)

这是我的 user.controller.js,我在我的 Route.js 中使用它,而它在我的 sever.js 中使用

const User = require('../models/user.model')
const jwt = require('jsonwebtoken')

exports.user_create = function (req, res, next) {
    let user = new User(
        {
            _id: Math.random().toString(36).substr(2, 5), // generate a random ID
            email: req.body.email,
            password: req.body.password,
            firstName: req.body.firstName,
            lastName: req.body.lastName,
            role: "user"
        }
    );

    user.save(function (err, registeredUser) {
        if (err) {
            return next(err);
        } 
        else {
            let payload = { subject: registeredUser._id}
            let token = jwt.sign(payload, 'secretKey')
            res.status(200).send({token})
        }

    })
}

exports.user_login = function (req, res, next) {
    let userData = req.body
    User.findOne({email: userData.email}, (err, user) => {
        if (err) {
            console.log(err)
        } 
        else {
            if (!user) {
                res.status(401).send('Invalid email')
            } 
            else if (user.password !== userData.password) {
                res.status(401).send('Invalid password')
            }
            else {
                let payload = {subject: user._id}
                let token = jwt.sign(payload, 'secretKey')
                //res.status(200).send({token})
                res.status(200).write({token})
                //let role = this.user.role
                // res.status(200).write({role})
                res.end()
            }
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

使用这个作品

res.status(200).send({token})
Run Code Online (Sandbox Code Playgroud)

但这并不

res.status(200).write({token})
res.end()
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 6

针对您问题的标题:

我可以使用 res.send(foo) 两次吗?

不,您不能针对同一个请求调用两次。

自从我写完第一部分后OP改变了他们的问题以来,请参阅答案的第二部分

在 Express 中,每个请求只能使用res.send()orres.json()res.end()一次。当您执行这些操作时,它会发送请求。如果您尝试针对同一请求发送更多内容,它将不会执行任何操作,并且会在 Express 中显示警告。

res.write()可以多次调用,然后在res.end()您最终完成请求时调用。

在你的例子中:

res.status(200).send({token})
res.end()
Run Code Online (Sandbox Code Playgroud)

已经对您res.send()进行了调用.end(),因此尝试再次调用它会被视为错误,因为请求已经发送。


仅供参考,.status(200)没有必要。默认状态已经是 200,因此res.send({token})已经具有 200 状态。


修改后的问题的最新答案

现在您已经完全将问题更改为 about res.write({token}),这不起作用,因为res.write()需要 aString或 aBuffer作为参数,而您给了它一个对象。您必须自己手动将对象转换为 JSON:

res.type('application/json');
res.write(JSON.stringify({token}));
res.end();
Run Code Online (Sandbox Code Playgroud)

请注意,这还设置了适当的内容类型。如果您的对象很大,res.write()您可能还需要注意写入缓冲区已满并侦听事件drainres.write()是比用于发送数据的 Express 函数低得多的级别设施(它位于 http 级别,而不是 Express 级别)。

内置于 Express 中,您可以使用res.send()res.json()哪些 Express 方法,它们会在您传递对象时自动将其转换为 JSON,并将内容类型也设置为 JSON。它还将处理写入流中的任何缓冲区已满问题。

res.send({token});
Run Code Online (Sandbox Code Playgroud)

或者,我更喜欢在我的 Express 代码中更加明确:

res.json({token});
Run Code Online (Sandbox Code Playgroud)

而且,如果您尝试发送多条数据,可以将它们放入同一个对象中:

res.json({token, role});
Run Code Online (Sandbox Code Playgroud)