Javascript node/express 4:在ajax post上使用express validator显示错误

Javascript node/express 4:在ajax post上使用express validator显示错误,javascript,node.js,ajax,validation,express,Javascript,Node.js,Ajax,Validation,Express,我不熟悉node,并且尝试在用户尝试提交表单时显示验证错误(使用express validator和express 4) 验证器似乎可以工作,因为如果我将数据记录到控制台,一切都会按照预期进行。但是,渲染视图时无法在页面上显示错误(不显示任何内容)。与我在express验证中遵循的“标准”教程的唯一区别在于,我使用AJAX发布数据 我的代码如下。我使用[…]表示我删除了更多的代码,为了简洁起见,我去掉了一些表单字段 app.js var express = require('express')

我不熟悉node,并且尝试在用户尝试提交表单时显示验证错误(使用express validator和express 4)

验证器似乎可以工作,因为如果我将数据记录到控制台,一切都会按照预期进行。但是,渲染视图时无法在页面上显示错误(不显示任何内容)。与我在express验证中遵循的“标准”教程的唯一区别在于,我使用AJAX发布数据

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

app.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;
$(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)
                }
              });        
  });     
});
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;
handle_members.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;
$(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)
                }
              });        
  });     
});
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;
members.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;
$(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)
                }
              });        
  });     
});
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;
index.jade

        [...]
                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
          [...]
登录到控制台时的错误变量如下所示:

[ { param: 'email', msg: 'not valid email', value: 'xxxx' },   { param: 'name', msg: 'can't be empty', value: '' } ]
在过去的几天里,我真的尝试了很多不同的东西,但没有一个奏效。问题似乎总是一样的:一切都很好,但当我渲染视图时,它好像从未进入“if errors…”语句。也许我在这里遗漏了一些非常基本的东西?非常感谢您的帮助,谢谢

最后,理想情况下,表单应该位于模式/弹出窗口中,以防更改某些内容。

第一次尝试 尝试在任何bodyParser中间件之后立即添加验证程序中间件,如要求:


第二次尝试 根据文档,错误似乎是具有
msg
param
属性的对象数组。尝试将您的jade代码更新为以下内容:

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

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

例如:

使用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 });
  });
});

谢谢,但我确实试过了。它一直都在那个位置,我最近的一次尝试是试图移动它,但在复制代码时忘了把它放回原处。谢谢你的尝试,但似乎不起作用。我没有在我的答案中包括,但即使避免循环,我只是试图在出现错误的情况下显示一个测试段落,但也没有显示出来。这让我猜测问题不在jade循环中,而是在其他地方。似乎它根本就没有进入那个if语句。顺便问一下,第二次尝试中的“我”是什么?你好像没用,它已经在那儿了。虽然没有文档,因为它还处于早期阶段。还有,有很多日语文本,希望不要太混乱。啊,当然,最新的更改和验证尝试尚未推出,所以不确定这会有什么帮助。创建服务器需要执行哪些步骤?我已经运行了
npm install
node app.js
。该应用程序没有您在答案中发布的一些代码。你能提交所缺少的所有内容吗?你能展示errors变量的样子吗?@MarceloAlves我当然更新了这个问题。