javascript - 在 node.js express 中返回响应的正确方法是什么?
问题描述
我无法理解我的代码有什么问题。我正在创建简单的 node.js REST api,无论我做什么都会出错:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:535:11)
at ServerResponse.header (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\express\lib\response.js:267:15)
at Query.<anonymous> (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\controllers\users.js:38:32)
at Query.<anonymous> (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
at Query.EofPacket (D:\04. MOJE\08. STUDIA\6 semestr\Wybrane technologie webowe\Projekt\silicon store api\node_modules\mysql\lib\protocol\sequences\Query.js:133:8) {
code: 'ERR_HTTP_HEADERS_SENT'
导致错误的代码如下:
exports.register = function (req, res) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
var userId;
// check whether email is taken
mysql.query(
'SELECT email FROM users where email = ?',
[req.body.email],
(err, rows, fields) => {
if (err) {
return res.sendStatus(500);
}
if (rows.length > 0) {
return res.status(400).json({
message: 'Mail taken',
});
}
}
);
// check whether name is taken
mysql.query(
'SELECT name FROM users where name = ?',
[req.body.name],
(err, rows, fields) => {
if (err) {
return res.status(500);
}
if (rows.length > 0) {
return res.status(400).json({
message: 'Name taken',
});
}
}
);
其中第 38 行是:
return res.status(400).json({ message: 'Name taken' });
但是响应是正确的,我收到错误 400,error
设置为Mail taken
据我了解,这与尝试多次发送响应有关。在检查姓名或电子邮件是否被占用后,注册功能不会结束。那里有更多的代码,但原理是一样的。
我不知道也无法在网上找到任何信息,什么是处理响应的正确方法。
解决方案
您要返回两次响应,这会导致cannot set headers
错误。您需要在第mysql.query
一个回调函数中运行第二个。或者,您可以使用async
await
.
exports.register = function (req, res) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
var userId;
// check whether email is taken
mysql.query(
'SELECT email FROM users where email = ?',
[req.body.email],
(err, rows, fields) => {
if (err) {
return res.sendStatus(500);
}
if (rows.length > 0) {
return res.status(400).json({
message: 'Mail taken',
});
}
// check whether name is taken
mysql.query(
'SELECT name FROM users where name = ?',
[req.body.name],
(nameErr, nameRows, fields) => {
if (nameErr) {
return res.status(500);
}
if (nameRows.length > 0) {
return res.status(400).json({
message: 'Name taken',
});
}
// if no errors, run the rest of your code here
}
);
}
);
}
推荐阅读
- actions-on-google - 如何解决 Google Actions Console 中的区域定位错误?
- java - Spring 4.x 在哪里放置 application.properties?
- php - ZipArchive::Create 的确切效果太模棱两可了
- hive - Hive:根据最大日期从一个表插入到另一个表中的所有缺失记录
- azure - 如何判断 Azure IoT 消费者组是否处于活动状态?
- android - 注意:无法读取获取 ...etc 的 kotlin 元数据和类型转换器
- ios - 如何在 Swift 中为多个 UIActionSheet 创建通用方法
- .net - 将 Target Framework 从 4.7 升级到 4.7.1 Nu-Get 无法恢复包
- http-headers - 浏览器是否在重定向响应中使用资源提示(链接)标头?
- c# - 可以忽略 finally-block 中的信号量释放吗?