Почему express говорит: «Не удается установить заголовки после их отправки клиенту» в моем коде? - PullRequest
0 голосов
/ 20 января 2020

Я создаю какой-то запрос / ответ на вход в систему Express. Когда пользователь вводит правильное имя пользователя и пароль, сервер возвращает действительный код авторизации.

Это код.

export const getAuthKey = async (req, res, next) => {
    // Query parameter : :username, :hash(SHA256 encoded pasword)
    // Return : { authKey: authKey }
    if (req.query.username === undefined) { res.status(400).send('`username` query paramter missing.'); }
    if (req.query.hash === undefined) { res.status(400).send('`hash` query paramter missing.'); }
    getConnection()
        .then(conn => new Promise((resolve, reject) => {
            const escapeUserName = conn.escape(req.query.username);
            const escapeSHA256 = conn.escape(req.query.hash);
            return conn.query(`SELECT HEX(AuthorizationKey) AS authKey FROM UserInfo WHERE UserName = ${escapeUserName} AND UserPassword = UNHEX(${escapeSHA256});`)
                .then(result => resolve(result))
                .catch(err => reject(err))
                .finally(() => { conn.end(); });
        }))
        .then(auth => {
            if (auth.length < 1) { res.status(401).send('No such user found'); }
            else { 
                log(`User ${req.query.username} requests valid authorization.`, `AUTH`)
                res.json(auth[0]); 
            }
        })
        .catch(err => {
            log('Unable to get authKey', 'AUTH', 'ERROR', err);
            res.status(500).send(`Unable to logging-in`);
        });
}

Шаги просты,

1. Пользователь отправляет запрос с параметром username и hash (пароль) 1-1. Если параметр не выполнен, он возвращает статус 400. 2. Проверьте базу данных и найдите, если пользователь действителен, если это так, верните его код авторизации. 3-2 При возникновении непредвиденной ошибки возвращает статус 500.

Этот код работает. Но я всегда вижу (node:11580) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Мне кажется, я что-то упускаю из-за запроса http. Можете ли вы сказать мне, что не так? Также не могли бы вы предоставить шаблон кода для такого рода процессов?

ps, пожалуйста, игнорируйте asyn c в определении функции.

1 Ответ

1 голос
/ 20 января 2020

Конкретная ошибка, которую вы спросили о «Невозможно установить заголовки после их отправки клиенту», вызвана попыткой отправить второй ответ на тот же запрос. Таким образом, обычно существует проблема с потоком в вашем коде, который заставляет его выполнять несколько путей кода, которые могут отправить ответ.

В этих двух операторах необходимо добавить оператор return, чтобы код выполнял не продолжать выполнение вашей функции после того, как вы отправили ответ:

if (req.query.username === undefined) { res.status(400).send('`username` query paramter missing.'); }
if (req.query.hash === undefined) { res.status(400).send('`hash` query paramter missing.'); }

Даже если вы вызвали res.send(), нормальное управление потоком Javascript по-прежнему применяется, а остальная часть вашей функции будет продолжать выполнить, в результате чего вы попытаетесь отправить другой ответ, который является источником предупреждения «заголовки уже отправлены».

Итак, добавьте возврат к каждому из этих операторов if, чтобы остановить дальнейшее выполнение функции после отправки ответа.

if (req.query.username === undefined) { 
    res.status(400).send('`username` query parameter missing.'); 
    return;
}
if (req.query.hash === undefined) { 
    res.status(400).send('`hash` query parameter missing.'); 
    return;
}

Я бы также предложил вам слегка изменить эти операторы if, чтобы включить больше условий, таких как пустые строки:

if (!req.query.username) { 
    res.status(400).send('`username` query parameter missing.'); 
    return;
}
if (!req.query.hash) { 
    res.status(400).send('`hash` query parameter missing.'); 
    return;
}

FYI, также исправьте написание слова " параметр».

...