Express.js 中的新 Mongoose Schema `ERR_HTTP_HEADERS_SENT` 错误
Posted
技术标签:
【中文标题】Express.js 中的新 Mongoose Schema `ERR_HTTP_HEADERS_SENT` 错误【英文标题】:New Mongoose Schema `ERR_HTTP_HEADERS_SENT` erorr in Express.js 【发布时间】:2021-09-09 10:52:27 【问题描述】:我的目标是
如果找到任何数据 findOne() 函数使用内容更新当前端点,如果没有使用 Schema 创建新元素。
问题
如果 db 中没有数据,那么首先if
它会将ERR_HTTP_HEADERS_SENT
与console.log = 1 相结合,但如果有,则使用console.log = 3 一切正常。
try
const find = await endPointSchema.findOne( uuid: uuid );
if (!find)
const data = new endPointSchema(
uuid: uuid,
endpoint: [ point: Endpoint, Content ],
date: Date.now(),
);
await data.save();
console.log(1);
res.status(200).json( message: "Succesfully Created new Breakpoint" );
return;
else
if (!find.endpoint)
console.log(2);
res.end();
return;
else
console.log(3);
res.end();
return;
catch (e)
console.log(e);
res.end();
return;
我的端点
route.post("/endpoint", AuthorizePanel, async (req, res) =>
const role, username, uuid = req.user;
if (!role && !username && !uuid)
res.sendStatus(401);
return;
const Endpoint, Content = req.body;
if (Endpoint === username)
res.status(403).json( message: "Endpoint can not be same with your username!" );
return;
try
const find = await endPointSchema.findOne( uuid: uuid );
if (!find)
const data = new endPointSchema(
uuid: uuid,
endpoint: [ point: Endpoint, Content ],
date: Date.now(),
);
await data.save();
console.log(1);
res.status(200).json( message: "Succesfully Created new Breakpoint" );
return;
else
if (!find.endpoint)
console.log(2);
res.end();
return;
else
console.log(3);
res.end();
return;
catch (e)
console.log(e);
res.end();
return;
);
授权面板
import jwt from "jsonwebtoken";
export const AuthorizePanel = (req, res, next) =>
const authHeader = req.headers.authorization;
if (authHeader)
const token = authHeader.split(" ")[1];
jwt.verify(token, process.env.JWT_SECRET, (err, user) =>
if (err)
res.sendStatus(403)
return
req.user = user;
next();
);
next();
;
【问题讨论】:
1 在不成功的流程中打印?数据是否保存? 是的,我知道这很有趣,但是在 http 标头错误之后我看到它已保存。 该错误通常是当您在发送一个响应后发送 res 时。查看您的代码,我不明白这是怎么回事。您可以在使用 res 的地方添加/检查更多代码流吗? 就像我无法理解的那样 可能在此函数之前的某个地方还有另一个 res.end() 或 res.send()。 【参考方案1】:问题在于 auth 中间件,如果您仔细查看 auth 中间件,您会注意到 jwt.verify 函数中的 return 语句仅针对该函数返回。 jwt.verify 函数执行后,next();
函数也可以工作。要打断你需要在你的第一个 if 块中添加 else 块
export const AuthorizePanel = (req, res, next) =>
const authHeader = req.headers.authorization;
if (authHeader)
const token = authHeader.split(" ")[1];
jwt.verify(token, process.env.JWT_SECRET, (err, user) =>
if (err)
res.sendStatus(403)
return
req.user = user;
next();
);
else
next();
;
【讨论】:
【参考方案2】:在 authorizePanel 中,将第二个 next 放在 else 条件中或将其删除(如果您只希望经过身份验证的用户继续前进)。 每次都会调用它。
为什么我认为有错误
为了简化,让我们用 mongoose call function A来调用函数。
您的 JWT 验证代码中有一个回调,因此将在将来某个时间点异步调用它。
如果用户遇到身份验证错误,则请求将尝试返回响应(异步)并调用函数 A(立即因为 if 外部的 next())将发送自己的响应。 此外,如果没有错误,则流程也将转移到功能 A。 (注意因为if条件之外的另一个next(),所以流程已经移到A了)。
在任何一种情况下,您的服务器都可能发送 2 个响应。一个带有 JWT 错误和您的第二个 函数 A。或者两者都来自您的函数 A。
可能会保存数据,但之后会出现错误,因为标头已发送,服务器正在尝试再次执行此操作。
【讨论】:
正如我所说,我使用了这个中间件功能,但我从未收到此错误。我认为问题出在端点功能上,所以您会问我如何确定这一点,因为当我替换此功能时,另一个功能不会出现此错误。 你的其他函数是否也发送响应?以上是关于Express.js 中的新 Mongoose Schema `ERR_HTTP_HEADERS_SENT` 错误的主要内容,如果未能解决你的问题,请参考以下文章
Express.js 项目中在哪里进行验证——在数据库层进行验证(re. Mongoose)?
node.js + express.js:使用 mongodb/mongoose 处理会话
在 Mongoose 模型中访问 Express.js 请求上下文