我的nodejs应用程序中的中间件弹出错误。中间件验证用户已获得获取讨论索引页面的权限。运行经过身份验证的用户时,出现错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后,无法设置标头。 循环会验证学生,但不会退出循环并继续到页面。当我与未经验证的学生一起运行代码时,它会按预期运行,并通过req.session.error消息重定向回去。我在附加了isEnrolled中间件的情况下执行任何路由时都会遇到这些错误,所以我知道问题出在该中间件中,因为在此之前一切正常。
我最初没有使用async / await尝试了该代码,但是它没有用。然后,我在forEach循环上将其切换为异步/等待,希望对您有所帮助。我试过使用标准的for循环,并在if / else语句中使用不同的变体。
下面是我的中间件文件,错误必须在加粗的isEnrolled中间件中
const middleware = {
asyncErrorHandler: (fn) =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
},
**isEnrolled: async (req, res, next) => {**
const course = await Course.findById(req.params.id).populate({
path: 'enrolls',
model: 'Enroll'
});
if (course.enrolls.length) {
course.enrolls.forEach(async enroll => {
if (enroll.status && enroll.student.equals(req.user._id)) {
console.log('status is ', enroll.status);
console.log('student is ', enroll.student);
console.log('user id is ', req.user._id);
await next();
}
});
}
req.session.error = 'Access Denied! You are not currently enrolled.';
res.redirect('back');
},
这是讨论路线
const express = require('express');
const router = express.Router({ mergeParams: true });
const { asyncErrorHandler, isDiscussionAuthor, isLoggedIn, isEnrolled } = require('../middleware');
const {
discussionIndex,
discussionNew,
discussionShow,
discussionCreate,
discussionDestroy
} = require('../controllers/discussions');
router.get('/', isLoggedIn, asyncErrorHandler(isEnrolled), asyncErrorHandler(discussionIndex));
router.get('/new', isLoggedIn, asyncErrorHandler(isEnrolled), asyncErrorHandler(discussionNew));
router.get('/:discussion_id', isLoggedIn, asyncErrorHandler(isEnrolled), asyncErrorHandler(discussionShow));
router.post('/', isLoggedIn, asyncErrorHandler(isEnrolled), asyncErrorHandler(discussionCreate));
router.delete('/:discussion_id', isLoggedIn, asyncErrorHandler(isDiscussionAuthor), asyncErrorHandler(discussionDestroy))
module.exports = router;
我希望这能击中next()语句,并在从当前用户验证用户并且enroll.status为true时继续进入讨论索引路由。相反,终端console.logs在窗口中显示它确实验证了用户,而是吐出一个错误并挂断。以下是我从终端收到的错误消息
status is 1
student is 5cdcab37c698904044cacd66
user id is 5cdcab37c698904044cacd66
GET /courses/5cdc931f786559570ca3c9a2/discussions 302 51.453 ms - 152
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (C:\Users\colton\upskill\node_modules\express\lib\response.js:767:10)
at ServerResponse.send (C:\Users\colton\upskill\node_modules\express\lib\response.js:170:12)
at done (C:\Users\colton\upskill\node_modules\express\lib\response.js:1004:10)
at C:\Users\colton\upskill\node_modules\ejs-mate\lib\index.js:285:7
at tryHandleCache (C:\Users\colton\upskill\node_modules\ejs-mate\node_modules\ejs\lib\ejs.js:257:5)
at Object.exports.renderFile (C:\Users\colton\upskill\node_modules\ejs-mate\node_modules\ejs\lib\ejs.js:482:10)
at renderFile (C:\Users\colton\upskill\node_modules\ejs-mate\lib\index.js:227:7)
at C:\Users\colton\upskill\node_modules\ejs-mate\lib\index.js:282:7
at tryHandleCache (C:\Users\colton\upskill\node_modules\ejs-mate\node_modules\ejs\lib\ejs.js:257:5)
at Object.exports.renderFile (C:\Users\colton\upskill\node_modules\ejs-mate\node_modules\ejs\lib\ejs.js:482:10)
at View.renderFile [as engine] (C:\Users\colton\upskill\node_modules\ejs-mate\lib\index.js:227:7)
at View.render (C:\Users\colton\upskill\node_modules\express\lib\view.js:135:8)
at tryRender (C:\Users\colton\upskill\node_modules\express\lib\application.js:640:10)
at Function.render (C:\Users\colton\upskill\node_modules\express\lib\application.js:592:3)
at ServerResponse.render (C:\Users\colton\upskill\node_modules\express\lib\response.js:1008:7)
at discussionIndex (C:\Users\colton\upskill\controllers\discussions.js:10:13)
at process._tickCallback (internal/process/next_tick.js:68:7)