node/express 4:在 AJAX POST 上使用 Express-Validator 显示错误



我是node的新手,当用户尝试提交表单时,我试图显示验证错误(使用express-validator和express 4(。

验证器似乎可以工作,因为如果我将数据记录到控制台,一切都符合预期。但是,当我呈现视图时,我无法在页面上显示错误(不显示任何内容(。与我一直遵循的快速验证"标准"教程的唯一区别是,我使用 AJAX 发布数据。

我的代码如下。我使用[...]来表示我删除了更多代码,并且为了简洁起见,我删除了一些表单字段。

应用.js

var express = require('express')
, indexController = require('./routes/index')
, membersController = require('./routes/members')
[...]
, cookieParser = require('cookie-parser')
, bodyParser = require('body-parser')
, expressValidator = require('express-validator');
var app = express();
[...]
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressValidator()) // tried both placing it here or below
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// I realize this may be not optimal
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', indexController);
app.use('/members', membersController);
[...]
module.exports = app;

handle_members.js

$(document).ready(function() {
$('#join_btn').click(function(event, req, res){
event.preventDefault(); 
var newMember = {
'name': $('#join_form input#join_name').val(),
'email': $('#join_form input#join_email').val()
}
$.ajax({
type: 'POST',
data: newMember,
url: '/members/addmember',
dataType: 'JSON'
}).done(function(response){
if (response.msg === 'success'){
alert('New member added successfully!')
}
// maybe this is not necessary?
else if (response.msg === 'validation'){  
alert('validation failed');
}
else{
alert('Error: ' + response.msg)
}
});        
});     
});

成员.js

var express = require('express');
var router = express.Router();
router.post('/addmember',validator, function(req, res) {
var db = req.db;
var collection = db.get('memberstest');
collection.insert(req.body, function(err, result){
res.send(
(err === null) ? { msg: 'success' } : { msg: err }
);
});
});

function validator(req, res, next) {
req.checkBody('email', 'not valid email').isEmail();
req.checkBody('name', 'cannot be empty').notEmpty();
var errors = req.validationErrors();
if (errors) {
console.log(errors) // these are as expected
res.render('index',{errors:errors}); // no errors displayed
}
else {
next();
}
};
module.exports = router;

索引.翡翠

[...]
form#join_form(method='POST', action='', role='form')
div.form-group
input#join_name.form-control(type='text', name='join_name')
input#join_email.form-control(type='email', name='email')
button#join_btn.btn(type='button') join
if errors
ul
for error in errors
li = error.msg
[...]

记录到控制台时的 errors 变量如下所示:

[ { param: 'email', msg: 'not valid email', value: 'xxxx' },   { param: 'name', msg: 'can't be empty', value: '' } ]

在过去的几天里,我真的尝试了很多不同的东西,但没有一个奏效。问题似乎总是相同的:一切都很好,但是当我渲染视图时,它就像它永远不会进入"如果错误......"陈述。也许我在这里缺少一些非常基本的东西?任何帮助都非常感谢,谢谢。

最终,理想情况下,表单应该在模态/弹出窗口中,以防万一更改某些内容。

第一次尝试

尝试在任何 bodyParser 中间件之后立即添加验证器中间件,如文档要求的那样:

var express = require('express')
, indexController = require('./routes/index')
, membersController = require('./routes/members')
[...]
, cookieParser = require('cookie-parser')
, bodyParser = require('body-parser')
, expressValidator = require('express-validator');
var app = express();
[...]
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressValidator()); // this line must be immediately after any of the bodyParser middlewares!
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// I realize this may be not optimal
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', indexController);
app.use('/members', membersController);
[...]
module.exports = app;

第二次尝试

根据文档,错误似乎是具有msgparam属性的对象数组。尝试将翡翠代码更新为以下内容:

ul
if errors
each error, i in errors
li #{error.msg}

第三次尝试

在分析了OP通过Github提供给我的代码后,我发现了问题所在。OP 使用 Ajax 调用将数据发送到后端,并使用 res.render 进行响应,这显然是错误的,因为res.render不是响应使用 Ajax 发出的请求,正确的方法是 res.json。

例:

使用 jQuery 调用/addmember端点:

var data = {}; // data here
$.ajax({
type: 'POST',
data: data,
url: '/addmember',
dataType: 'JSON'
}).done(function() {
alert('done');
}).fail(function() {
alert('fail');
});

使用res.json从后端回答:

router.post('/addmember', (req, res) => {
var db = req.db;
var collection = db.get('memberstest');
collection.insert(req.body, (error, result) => {
if (error)
return res.json({ error });
return res.json({ result });
});
});

最新更新