Могу ли я использовать res.send (foo) дважды? - PullRequest
0 голосов
/ 02 декабря 2019

Я хочу отправить свой токен и роль моего пользователя на мой login.component.ts.

Когда я пытался найти проблему, в моем исследовании я наткнулся на чье-то предложение использовать

res.write(foo1)
res.write(foo2)
res.end

Вместо

res.send(foo1)
res.send(foo2)

Но это не сработало. Затем я попытался использовать это, чтобы проверить это:

res.write(foo1)
res.end()

Но это дает мне ошибку:

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\micha\GitHub\se3316-mdsilva6-lab5\server\controllers\user.controller.js:46:33)
    at C:\Users\micha\node_modules\mongoose\lib\model.js:4604:16
    at C:\Users\micha\node_modules\mongoose\lib\query.js:4348:12
    at process.nextTick (C:\Users\micha\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\micha\node_modules\mongoose\lib\model.js:4606:13
    at C:\Users\micha\node_modules\mongoose\lib\query.js:4348:12
    at process.nextTick (C:\Users\micha\node_modules\mongoose\lib\query.js:2850:28)
    at process._tickCallback (internal/process/next_tick.js:61:11)

Это мой user.controller.js, который я использую в своем маршруте.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()
            }
        }
    })
}

Использование этого работает

res.status(200).send({token})

Но это не

res.status(200).write({token})
res.end()

Ответы [ 3 ]

1 голос
/ 02 декабря 2019

В ответ на заголовок вашего вопроса:

Можно ли использовать res.send (foo) дважды?

Нет, вы не можете вызвать его дважды длятот же запрос.

См. вторую часть ответа, поскольку ОП изменил свой вопрос после того, как я написал эту первую часть

В Express вы можете использовать только res.send()или res.json() или res.end() один раз за запрос. Когда вы выполняете их, он отправляет запрос. Если вы попытаетесь отправить больше по одному и тому же запросу, он ничего не сделает и в Express выдаст предупреждение.

res.write() может быть вызвано несколько раз, после чего следует res.end(), когда вы, наконец, закончитес запросом.

В вашем примере:

res.status(200).send({token})
res.end()

res.send() уже вызывает .end(), поэтому попытка его повторного вызова считается ошибкой, поскольку запрос уже былотправлено.


К вашему сведению, .status(200) не обязательно. Состояние по умолчанию уже 200, поэтому res.send({token}) уже будет иметь статус 200.


Более недавний ответ на измененный вопрос

Теперь, когда выполностью изменил вопрос на res.write({token}), это не работает, потому что res.write() требует String или Buffer в качестве аргумента, и вы дали ему объект. Вам нужно будет либо вручную конвертировать объект в JSON:

res.type('application/json');
res.write(JSON.stringify({token}));
res.end();

И учтите, что это также устанавливает соответствующий тип контента. Если ваш объект имеет большой размер res.write(), возможно, вам также придется обратить внимание на переполнение буфера записи и прослушать событие drain. res.write() - это средство гораздо более низкого уровня (на уровне http, а не на уровне Express), чем функции Express для отправки данных.

Встроенный в Express, вы можете использовать res.send() или res.json()которые представляют собой методы Express, которые будут одновременно передавать объект, автоматически преобразовывать его в JSON и также устанавливать тип содержимого JSON. Он также будет обрабатывать любые проблемы с заполнением буфера в потоке записи.

res.send({token});

или, я предпочитаю быть более явным в моем коде Express с:

res.json({token});

И, если выпытаясь отправить несколько фрагментов данных, вы можете поместить их в один и тот же объект:

res.json({token, role});
0 голосов
/ 02 декабря 2019

Я нашел решение: я могу отправить несколько вещей в res.send (...)

res.status(200).send({token, role})
0 голосов
/ 02 декабря 2019

Вызов res.status(200).send({ token }) завершает запрос и отправляет объект обратно клиенту ...

Поскольку запрос завершен ... При вызове res.end() выдается ошибка ...

Вы бы обычно использовали res.end, если бы вы передавали некоторые данные (обычно двоичные) после нескольких res.write, чтобы закрыть канал ...

Для получения дополнительной информации ... оформить документы Express вобъект ответа ...

https://expressjs.com/en/api.html#res

Также ... Вы не можете отправить объект, используя res.write ...

Из вашей ошибки ... он говорит, что он изначально принимает строку или буфер. Если вы хотите отправить простые объекты ... res.send или res.json будет более подходящим ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...