nodejs 不接受 ajax 的表单数据
nodejs not accept form data by ajax
我正在使用节点 4.3.1,express 4.13.1,身份验证工具是 local-passport。我正在尝试 post 通过 ajax 登录表单数据。所以我想在不刷新页面的情况下显示错误消息。但第一步就是要我的命。
查看:
<form id="login_form" action="#">
<input type="hidden" id="csrf" name="_csrf" value="{{_csrfToken}}">
<input id="email" name="email" type="email" placeholder="Email">
<input id="password" name="password" type="password" placeholder="Password">
<button type="" id="forLogin">Login</button>
</form>
//POST Ajax
$('#forLogin').on('click', function(e){
e.preventDefault();
var data= {};
data.email = $('#email').val();
data.password = $('#password').val();
data._csrf = $('#csrf').val();
$.ajax({
type: 'POST',
url: '/login',
data: JSON.stringify(data), // node.js accepts request but responds 403
// data: $('#login_form').serialize(),
// don't accept any request
dataType: 'json',
// headers: {'X_CSRF_TOKEN':'{{_csrfToken}}'},
// not working too
success: function(result){
console.log('success');
if(!result){
console.log('No result');
}
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr.status);
console.log(thrownError);
}
});
});
如果我使用 data: JSON.stringify(data)
,firefox 检查器会显示非常可疑的参数:
{"email":"test@gmail.com","password":"test","_csrf":"wOEsa4s2-I9dmSQuT9djm0kyrrp9WcZWj6U0"}:""
即使这个参数通过得很好,我也不确定它是否会起作用。
并且在这些情况下:data: $('#login_form')
或 data:data
我没有收到任何回复。但参数似乎合理且关键:attr 对看起来很整齐。
router.js
router.post('/login', function(req, res, next){
passport.authenticate('local-login', function(err, user, info){
console.log(req.body);
if (err) { return next(err); }
if (!user) {
console.log('authentication fail');
return res.json({ajaxMsg: 'authentication fail'});
}
req.logIn(user, function(err) {
if (err) { return next(err); }
// Redirect if it succeeds
return res.redirect('/');
});
})
});
passport.js
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('../models/User.js'),
bcrypt = require('bcrypt');
passport.serializeUser(function(user, done){
done(null, user.email);
});
passport.deserializeUser(function(email, done){
User.findOne(email, function(err, user){
done(err, user);
});
});
passport.use('local-login',
new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done){
User.findOne({'email': email}, function(err, user){
if(err) return done(err);
if(!user){
console.log('wrong email');
req.flash('email', req.body.email);
return done(null, false, req.flash('error_messages', 'No user found'));
}
if(!user.authenticate(password)){
console.log('wrong password');
req.flash('email', req.body.email);
return done(null, false, req.flash('error_messages', 'Password does not Match'));
}
console.log('Login Success');
return done(null, user);
});
})
);
module.exports = passport;
我意识到如果不刷新页面就无法使用 connect-flash 消息,所以我尝试替换其他逻辑很难理解 done() 方法的工作原理
而不是
if (err) { return next(err); }
尝试
if (err) { return res.json({error: err}); }
如果您遇到错误,则必须解决这个问题,但我相信那是您的问题。您的请求是在您的记录器上返回 404 还是 500?
Done 是它用于填充 req.session 对象的回调。
此外,我认为您没有正确使用 next()
。除非你的 /login
是某种中间件,并且你期望它结束后会发生其他事情
我解决了问题。
router.post('/login', function(req, res, next) {
if(req.body.email.length == 0 || req.body.password.length == 0) {
return res.json({error: 'enter a id and a pw'});
}
passport.authenticate('local-login', function(err, user, info) {
if (err) {
return res.json({srverror: err});
}
// Redirect if it fails
if (!user) {
return res.json({error: info.msg});
}
if (user) {
req.logIn(user, function(err) {
if (err) { return res.json({srverror: err}); }
// Redirect if it succeeds
res.send({redirect: '/'});
});
}
})(req, res, next);
});
(req, res, next) 是我需要的代码。
但我不能完全理解它为什么有效。
我正在使用节点 4.3.1,express 4.13.1,身份验证工具是 local-passport。我正在尝试 post 通过 ajax 登录表单数据。所以我想在不刷新页面的情况下显示错误消息。但第一步就是要我的命。
查看:
<form id="login_form" action="#">
<input type="hidden" id="csrf" name="_csrf" value="{{_csrfToken}}">
<input id="email" name="email" type="email" placeholder="Email">
<input id="password" name="password" type="password" placeholder="Password">
<button type="" id="forLogin">Login</button>
</form>
//POST Ajax
$('#forLogin').on('click', function(e){
e.preventDefault();
var data= {};
data.email = $('#email').val();
data.password = $('#password').val();
data._csrf = $('#csrf').val();
$.ajax({
type: 'POST',
url: '/login',
data: JSON.stringify(data), // node.js accepts request but responds 403
// data: $('#login_form').serialize(),
// don't accept any request
dataType: 'json',
// headers: {'X_CSRF_TOKEN':'{{_csrfToken}}'},
// not working too
success: function(result){
console.log('success');
if(!result){
console.log('No result');
}
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr.status);
console.log(thrownError);
}
});
});
如果我使用 data: JSON.stringify(data)
,firefox 检查器会显示非常可疑的参数:
{"email":"test@gmail.com","password":"test","_csrf":"wOEsa4s2-I9dmSQuT9djm0kyrrp9WcZWj6U0"}:""
即使这个参数通过得很好,我也不确定它是否会起作用。
并且在这些情况下:data: $('#login_form')
或 data:data
我没有收到任何回复。但参数似乎合理且关键:attr 对看起来很整齐。
router.js
router.post('/login', function(req, res, next){
passport.authenticate('local-login', function(err, user, info){
console.log(req.body);
if (err) { return next(err); }
if (!user) {
console.log('authentication fail');
return res.json({ajaxMsg: 'authentication fail'});
}
req.logIn(user, function(err) {
if (err) { return next(err); }
// Redirect if it succeeds
return res.redirect('/');
});
})
});
passport.js
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('../models/User.js'),
bcrypt = require('bcrypt');
passport.serializeUser(function(user, done){
done(null, user.email);
});
passport.deserializeUser(function(email, done){
User.findOne(email, function(err, user){
done(err, user);
});
});
passport.use('local-login',
new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done){
User.findOne({'email': email}, function(err, user){
if(err) return done(err);
if(!user){
console.log('wrong email');
req.flash('email', req.body.email);
return done(null, false, req.flash('error_messages', 'No user found'));
}
if(!user.authenticate(password)){
console.log('wrong password');
req.flash('email', req.body.email);
return done(null, false, req.flash('error_messages', 'Password does not Match'));
}
console.log('Login Success');
return done(null, user);
});
})
);
module.exports = passport;
我意识到如果不刷新页面就无法使用 connect-flash 消息,所以我尝试替换其他逻辑很难理解 done() 方法的工作原理
而不是
if (err) { return next(err); }
尝试
if (err) { return res.json({error: err}); }
如果您遇到错误,则必须解决这个问题,但我相信那是您的问题。您的请求是在您的记录器上返回 404 还是 500?
Done 是它用于填充 req.session 对象的回调。
此外,我认为您没有正确使用 next()
。除非你的 /login
是某种中间件,并且你期望它结束后会发生其他事情
我解决了问题。
router.post('/login', function(req, res, next) {
if(req.body.email.length == 0 || req.body.password.length == 0) {
return res.json({error: 'enter a id and a pw'});
}
passport.authenticate('local-login', function(err, user, info) {
if (err) {
return res.json({srverror: err});
}
// Redirect if it fails
if (!user) {
return res.json({error: info.msg});
}
if (user) {
req.logIn(user, function(err) {
if (err) { return res.json({srverror: err}); }
// Redirect if it succeeds
res.send({redirect: '/'});
});
}
})(req, res, next);
});
(req, res, next) 是我需要的代码。 但我不能完全理解它为什么有效。