PassportJS serializeUser报错:Can't set headers after they are sent 求助
解决PassportJS中"Can't set headers after they are sent"错误
我一眼就注意到你代码里的一个语法错误,这大概率就是导致重复发送响应的元凶!
问题根源:多余的回调函数导致两次调用done()
看你策略代码里的这段逻辑:
if (!req.user) { // 一系列异步检查和数据库操作,最后调用done() }, function(err){ return done(null, false, {message: err}) } )
这里的语法完全错误!if语句的结构是if(条件){代码块}[else{代码块}],你在if的代码块结束后加了一个逗号和独立的function(err){...},这个函数会被当作独立的表达式立即执行——不管!req.user的条件是否成立,它都会调用done(null, false, ...)。同时,if块里的异步操作(比如数据库插入完成后)也会调用一次done(),两次done()调用就会让Passport尝试两次发送响应头,直接触发Error: Can't set headers after they are sent。
修复方案
把这个多余的逗号和回调函数删掉即可,修复后的核心代码片段如下:
} else { var password = bcrypt.hashSync(_password, bcrypt.genSaltSync(10)); var companySelected = JSON.parse(req.body.companySelected); if (!req.user) { checkCompanyRegistrationStatus(companySelected.company_number, function(){ checkUserRegistrationStatus(_email, function(){ checkPasswordStrength(_password, function(){ maindb.MainDBInsert("INSERT INTO Uncomplete_Users_Registrations (first_name, last_name, password, email, company_registrat_number, company_name) OUTPUT Inserted.id VALUES (?, ?, ?, ?, ?, ?);", [req.body.firstName, req.body.lastName, password, _email, companySelected.company_number, companySelected.title], function(user, rowsCount){ return done(null, user[0]); }, function(code, err){ return done(null, false, {message: err}); } ); }, function (err) { return done(null, false, {message: err}); }) }, function(err){ return done(null, false, {message: err}) } ) }, function(err){ return done(null, false, {message: err}) } ) } // 删掉了原本多余的`, function(err){...}`代码块 } else { // 用户已登录且已有本地账户,请先登出再创建新账户 return done(null, req.user); }
额外建议
你现在嵌套了多层异步回调,代码可读性很差,后续排查问题也会更麻烦。建议用Promise或者async/await重构这部分逻辑,能更清晰地处理异步流程,也能避免这类回调嵌套导致的低级语法错误。
内容的提问来源于stack exchange,提问作者0xtuytuy
相关产品推荐
相关产品推荐

