[英]Mongodb error: Cannot set headers after they are sent to the client
I am basically creating a user registration form where I check if the submitted passwords match and then check if the user already exists by querying the collection to see if the submitted username or email already exist.我基本上是在创建一个用户注册表单,在其中检查提交的密码是否匹配,然后通过查询集合来检查用户是否已经存在,以查看提交的用户名或 email 是否已经存在。 If all of the data passed the checks then I create I new user.
如果所有数据都通过了检查,那么我将创建新用户。 My issue is that if the username or email already exist then the user is still created.
我的问题是,如果用户名或 email 已经存在,那么仍然会创建用户。 Shouldn't returning a status if a user is found stop the function?
如果发现用户停止 function,不应该返回状态吗?
Front end submission:前端提交:
submitNewUser() {
axios.post('http://localhost:5000/api/settings/users', {
name: this.newUser.name,
username: this.newUser.username,
email: this.newUser.email,
password: this.newUser.password,
confirm_password: this.newUser.confirm_password,
role: this.newUser.role
})
.then(() => {
this.getUsers();
})
.catch(error => {
console.log(error);
})
}
The user has to be signed in to create a new user so I user passport check if token contains a valid user用户必须登录才能创建新用户,因此我使用用户护照检查令牌是否包含有效用户
passport authentication check:护照认证检查:
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../models/User');
const key = require('./keys').secret;
const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = key;
module.exports = passport => {
passport.use(
new JwtStrategy(opts, (jwt_payload, done) =>{
User.findById(jwt_payload._id).then(user => {
if (user) return done(null, user);
return done(null, false);
}).catch(err => {
console.log(err);
});
})
);
};
End route:结束路线:
router.post('/users', passport.authenticate('jwt', {
session: false
}), (req, res) => {
let companyId = req.user.company_id;
let {
name,
username,
email,
password,
confirm_password,
role,
} = req.body;
//Check that passwords match
if( password !== confirm_password ) {
return res.status(400).json({
msg: "Passwords do not match"
})
}
//Check for unique username
User.findOne({ username: username })
.then(user => {
console.log('username')
if(user) {
return res.status(400).json({
msg: "Username is already taken."
});
}
})
.catch(error => console.log(error));
//check for unique email
User.findOne({ email: email })
.then(user => {
console.log('email')
if(user) {
return res.status(400).json({
msg: "Email is already registered. Did you forget your password?"
});
}
})
.catch(error => console.log(error));
let newUser = new User({
name,
username,
password,
email,
user_role: role,
company_id: companyId,
});
// Hash password
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err) throw err;
newUser.password = hash;
newUser.save()
.then(user => {
return res.status(201).json({
success: true,
msg: "User is now registered."
});
})
.catch(error => console.log(error));
});
});
});
This is an error that I get if the user already exists:如果用户已经存在,这是我得到的错误:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:482:11)
at ServerResponse.header (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\node_modules\express\lib\response.js:267:15)
at User.findOne.then.user (C:\Users\Reece\OneDrive\Desktop\Fyber Docs\Valentis-Pipeline-MEVN-App\server\routes\api\settings.js:106:40)
at processTicksAndRejections (internal/process/next_tick.js:81:5)
Due to the async nature, (req, res) => {
is returning before any of your calls to mongodb are either succeeding or failing, yet you still use the res
object to send a response back to the client.由于异步性质,
(req, res) => {
在您对 mongodb 的任何调用成功或失败之前返回,但您仍然使用res
object 将响应发送回客户端。
I don't know exactly how to deal with this in the framework you're using, but the framework appears to populate res
's header with data and send it back to the client before you start to modify the res
object.我不确切知道如何在您使用的框架中处理这个问题,但该框架似乎会在您开始修改
res
object 之前使用数据填充res
的 header 并将其发送回客户端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.