12

我正在使用 Node.js(使用 Express)编写一个非常基本的注册表单,并且我正在尝试找到提供基本表单验证的最简单方法。我选择了“Express-Validator”,这似乎做得很好。但是,我的目标是简单地显示所需的任何验证消息,并保留用户输入的值。

似乎请求信息没有回到 res.render 中,我想这是有道理的。但是,我到处寻找我能想到的地方,但找不到任何讨论如何在显示错误消息后保持表单字段填充的参考。

下面是一个描述我的方法的小片段:

post: function(req, res){

            var userName = req.body.username;
            var password = req.body.password;

            //Validate input
            req.assert("username", 'Invalid email address.').isEmail();
            req.assert("password", 'Password cannot be empty.').notEmpty();
            req.assert("passwordConfirm", 'Passwords entered do not match!').equals(password);

            //Make sure we have no validation errors
            var pageErrors = req.validationErrors();
            if(!pageErrors)
            {
                userModel.CreateUser(userName, password, function(err){
                    if(err)
                    {
                        //there was a problem inserting new user... probably already exists
                        //will need to check the error to confirm
                        var dbErrorMessage = "Could not insert record into database!";
                        if(err.code === 11000)
                        {
                            //this is a duplicate entry
                            dbErrorMessage = "A user with that email address already exists!";
                        }

                        res.render('register.html', { pageErrors: [{msg: dbErrorMessage }]});
                    }
                    else
                    {
                        res.render('register.html', { successMessage: successMessage });
                    }
                });
            }
            else
            {
                res.render('register.html', { pageErrors: pageErrors });
            }
4

7 回答 7

12

Unfortunately, you have to repopulate the form manually. If you get any page errors, you will pass back the form values to the view.

        if(!pageErrors)
        {
            // ...
        }
        else
        {
            res.render('register.html', { 
                pageErrors: pageErrors,
                userName: userName
            });
        }

And in your view, you would do a simple check to see if their are any errors and repopulate accordingly. You would have to keep track of what errors are produced for each form field.

<% if (userNameError) { %>
    <input type="text" name="userName" value="<%- userName %>" />
<% } else { %>
    <input type="text" name="userName" />
<% } %>

Another popular way is to send your form via ajax to to the server, and do all your validations. If there is an error, the entered form data remains and you would show the error, otherwise redirect after the successful login. Below is an example of how to submit a form with javascript.

$("#login-button").live("submit", function (e) {

    // this will prevent the form from being uploaded to the server the conventioanl way
    e.preventDefault();

    // the form data
    var data = $(this).serialize();

    // this logs the user in 
    $.ajax({
        type: 'POST',
        url: BASE_URL + '/login',
        data: data,
        dataType: 'json',
        success: function (data, status) {
            // successful
        },

    });

    // superfluous fallback
    return false; 
}); 
于 2012-11-28T07:05:55.693 回答
5

There is an easy way is you are using

app.use(express.bodyParser()) and app.use(expressValidator());

You can use req.body

res.render('register.html', { 
         pageErrors: pageErrors,
         validated: req.body
   });

And I'm not sure which templating language you are using but you could do something like..

<input type="text" name="userName" value="<%= pageErrors.userName.value || validated.userName %>" />

This then gives back the good input if ok or the bad input if it needs correcting.

于 2013-10-08T11:19:58.183 回答
3

You can get this done using connect-flash

Below are the code snippets in different files in order to get the values entered by the user back in form when validations fail while doing signup with passport.

Run this below command to add new package into package.json

npm install connect-flash --save

app.js

var flash = require('connect-flash');

app.use(flash()); // add this above passport initialize
app.use(passport.initialize());
app.use(passport.session());

config/passport.js (Please focus on form data loading into flash)

passport.use('local.signup', new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
}, function (req, email, password, done) {
    req.checkBody('first_name', 'Firstname is missing').notEmpty();
    req.checkBody('last_name', 'Lastname is missing').notEmpty();
    req.checkBody('email', 'Invalid email').notEmpty().isEmail();
    req.checkBody('password', 'Password is too short. Minimum size is 6.').notEmpty().isLength({min:6});
    req.checkBody('confirm_password', 'Password and confirm password didn\'t not match').equals(req.body.password);
    var errors = req.validationErrors();
    if (errors) {
            var messages = [];
            errors.forEach(function(error) {
                 messages.push(error.msg);
            });
            req.flash('formdata', req.body); // load form data into flash
            return done(null, false, req.flash('error', messages));
    }
    User.findOne({'email': email}, function (err, user) {
            if (err) {
                    req.flash('formdata', req.body); // load form data into flash
                    return done(err);
            }
            if (user) {
                    req.flash('formdata', req.body); // load form data into flash
                    return done(null, false, {message: 'Email is already in use.'});
            }
            var newUser = new User();
            newUser.first_name = req.body.first_name;
            newUser.last_name = req.body.last_name;
            newUser.email = email;
            newUser.password = newUser.encryptPassword(password);
            newUser.save(function(err, result) {
                 if (err) {
                         return done(err);
                 }
                 return done(null, newUser);
            });
    });
}));

routes/index.js (Please focus on form data in flash loaded back into a variable)

    router.get('/signup', function (req, res, next) {
    var messages = req.flash('error');
    var formdata = req.flash('formdata'); // Get formdata back into a variable   
    res.render('user/signup', {csrfToken: req.csrfToken(),
        messages: messages, // pass it here to access in view file
        hasErrors: messages.length > 0,
        formData: formdata[0]
    });
});

router.post('/signup', passport.authenticate('local.signup', {
        badRequestMessage: 'Please fill the form with all details',
        failureRedirect: '/user/signup',
        failureFlash: true
    }), function (req, res, next) {
        if (req.session.oldUrl) {
            var oldUrl = req.session.oldUrl;
            req.session.oldUrl = null;
            res.redirect(oldUrl);
        } else {
            res.redirect('/user/profile');
        }
});

views/signup.hbs (Please focus on values in input elements)

<form class="wow fadeInUp animated" data-wow-delay=".7s" action="/user/signup" method="post" >
    <input type="text" placeholder="First Name" name="first_name" value="{{ formData.first_name }}">
    <input type="text" placeholder="Last Name" name="last_name" value="{{ formData.last_name }}">
    <input type="text" class="email" placeholder="Email Address" name="email" value="{{ formData.email }}">
    <input type="password" name="password" value="" class="lock" placeholder="Password">
    <input type="password" name="confirm_password" value="" class="lock" placeholder="Confirm Password">
    <input type="hidden" name="_csrf" value="{{ csrfToken }}">
    <input type="submit" name="Register" value="Register"></form>

Hope this helps.

于 2016-09-22T07:06:24.850 回答
0

set a variable for all the input, for example

var inputData = {
  firstname : req.body.firstname,
  lastname : req.body.lastname,
  email : req.body.email,
  username : req.body.username,
  password : req.body.password,
  password_confirmation : req.body.password_confirmation,
  agreetoterms: req.body.agreetoterms
}

and then pass that variable to the view

res.render('register.html', { pageErrors: [{msg: dbErrorMessage }], inputData: inputData });

then in your view

value="<%= inputData.userName %>"
于 2016-06-13T20:14:10.790 回答
0

if you are using jade and form Validator from npm , the best part is that you can an if statement in jade and then you simply check if error then with res.render we send the objects also . See This

if(errors){
    res.render('register',{
        errors : errors,
        name : name,
        email : email,
        username : username,
        password : password,
        password2 : password2
    });

And in jade you do this

input.form-control(name='name',type='text',placeholder='Enter Name',value = (errors ? '#{name}':''))

so if there is errors value will set to variable in name which will rendered when we send back

I think you can also be done in Angular2/Angular.js

于 2017-07-21T01:52:47.547 回答
0

Well, there is a simple way to achieve this. Do following in controller:

else{
    res.render('register.html', { pageErrors: pageErrors, inputData: req.body});
}

Now, in your ejs (or do it according to your view engine) file do following:

<input type="text" name="name" value="<% if(typeof pageErrors !== "undefined"){ %> <%- inputData.name %> <% } %>" class="form-control">
于 2021-09-17T05:41:40.167 回答
-1

check http://www.quietless.com/kitchen/building-a-login-system-in-node-js-and-mongodb/

on register.html make this

    var data = {};
        data.user = $('#user-input').val();
        data.email = $('#email-input').val();
        data.pass = $('#pass-input').val();
    $.ajax({ url: '/signup'
           , type: 'POST'
           , data: JSON.stringify(data)
           , contentType: 'application/json'
           , dataType: 'html'
        })
        .done(function(data) {
            if (data == 'ok') {
                $('#content').html('You are registered!');
            }
            else $('#account-form-container').append('<br>error:' + data);
        });

there might be error like: CANNOT POST /

in this case the author of tutorial on link above uses lib $.ajaxForm

you can also use https://github.com/felixge/node-formidable

or $('#myform').submit() replace to $('#submit-a-link').click()

于 2012-11-28T08:51:44.320 回答