所以我正在尝试对快速中间件进行编程,并且我对每个
res.json()
或 res.send()
使用 return 语句,但我仍然收到错误:
Error [ERR_HTTP_HEADERS_SENT]: Cannot remove headers after they are sent to the client
我的 Express 中间件运行对象,但在 Express 服务器开始侦听之前,它们会被转换为其原始函数。
代码:
// first contact for all routes
_app.all("*", (req, res, next) => {
if(next == null || next == undefined) return res.json(null);
// Has user logged in?
info("Connection from: ", req.header("x-forwarded-for") || req.socket.remoteAddress);
if (!hauth(req)) {
// they havent
res.locals.authed = false;
if (req.route.path == NEW_AUTH_ROUTE) {
// get user credentials, validate, and create new session for user.
const auth = newauth(req);
// returns new auth key if user credentials are valid,
// otherwise an error prompting the user to login again.
return res.json(auth == null ? ServerResponse.authFail : prepareResponsePayload(auth));
}
// tells the console that the guest user is unauthorized,
// and passes false to the next() functions authed parameter, indicating
// the custom route defined that the user is un-authed. Some pages such as
// the profile page or account page will reject access instantly if this field is false.
warning("Un-authed user with auth header of: ", req.headers[AUTH_HEADER_NAME] || "NONE");
}
else
{
res.statusCode = 200; // can be changed in next() function
res.locals.authed = true;
}
/**
* -----------------
* - READ HERE -
* -----------------
*
* All custom routes created in this file must return their json response.
* The returned value can be anything, even null. It is good practice to be an object.
*
* The next function from your route also contains a field in the res object specifying
* if the user is authenticated or not:
* @see res.locals.authed
*
* If your return value is an error, examples like on line 25 show how to properly use them.
*
* @see ServerResponse houses static constants used for different responses. Includes errors.
* @see ServerSideError An object wrapper for an error recieved from the server.
*
* @see prepareResponsePayload prepareResponsePayload will prepare whatever is returned from next() to be sent back. Please read its contents.
*
*/
res.json(prepareResponsePayload(next()));
})
// init routes
for (const route of Object.values(routes)) {
try {
switch (route.method) {
case "POST": {
_app.post(route.method, route.func);
break;
}
case "DELETE": {
_app.delete(route.method, route.func);
break;
}
case "ALL": {
_app.all(route.method, route.func);
break;
}
case "PUT": {
_app.put(route.method, route.func);
break;
}
default: {
_app.get(route.method, route.func);
break;
}
}
info("Registered route '" + route.route + "'. ");
} catch (e) {
fatal("Route could not be established. Name: " + route.route)
}
}
_app.listen(SERVER_LISTEN_PORT, () => {
info("Server Listening on " + SERVER_LISTEN_PORT + ".");
})
这些评论是针对我的合作者的...
这是我定义路线的地方:
/**
* @type {Object.<string, Route>}
*/
module.exports.routes = {}
/**
* Route for pinging the server. Mostly for testing.
*/
module.exports.routes.
ping = new Route("GET", "/ping", async (req, res, next) => null); // all we are looking for is a ping, so no payload body is provided.
module.exports.routes.
register = new Route("POST", "/register", async (req, res, next) => {
try {
info("Route...");
const { username, email, password } = req;
if (!vparams(username, email, password)) return new ServerSideError(1, "Please provide all required fields.");
if (!vname(username)) return new ServerSideError(2, "Invalid Username.");
if (!vemail(email)) return new ServerSideError(3, "Invalid Email.");
if (!vpass(password)) return new ServerSideError(4, "Invalid Password.");
return new Promise((resolve, reject) => {
sql_addRow(new SQLRow({ username: username, password: password, email: email }, SQLTables.WEB_USERS),
(success, error) => {
if (error || !success) resolve(new ServerSideError(ServerSideError.ErrorCodes.OTHER, "Something unexpected happened."));
resolve(newauth(req));
});
});
} catch (e) { return new ServerSideError(-2, "Unexpected Error."); }
});
当我运行
postman
请求 /register
时,我收到此错误。我应该看别的东西吗?我已经检查了我的代码并查看了其他论坛,但他们都说我正在发送 2 个以上的回复,但我在这里看不到。感谢您提前的帮助!
这个本身:
res.json(prepareResponsePayload(next()));
是一个问题。您既发送响应又调用
next()
,这将导致其他路由能够处理此请求,从而导致发送重复的响应。
如果您发送回复,请勿致电
next()
。