简体   繁体   中英

Trying to figure out how to use a form from client to server side and in reverse using mongodb, node, and html?

I am a beginner here. I currently am working with twitter bootstrap (html,css,js), node.js for server side of things, mongodb for no-sql dbs. I have been looking at a bunch of things and am looking for an answer or any direction for how to go about having a form ie a user account registration to be filled out on the html side (already have this done)

<code> 
<form class="validateForm" id="registerform" method="POST" action=""  accept-charset='UTF-8'>
    <fieldset>
        <legend>Register</legend> <br>
            <input type="text" name="firstName" id="firstName" placeholder="First Name"     maxlength="20" value=""/> <br>
            <input type="text" name="lastName" id="lastName" placeholder="Last Name" maxlength="20" value=""/> <br>
            <input type="text" name="email" id="email" placeholder="Email" maxlength="30" value=""/> <br>
            <input type="password" name="password" id="password" placeholder="Password" value=""/> <br>
            <input type="password" name="confirmPassword" id="confirmPassword"placeholder="Confirm Password" value=""/> <br>
            <input type="text" name="phoneNumber" id="phoneNumber" placeholder="Phone Number" maxlength="10" value=""/> <br>
            <input type="date" name="birthday" id="birthday" placeholder="Birthday" value=""/>    
            <br>
            <label id="legalConfirm" for="agree"><input type="hidden" name="agree" value="0"  />
            <input type="checkbox" name="agree" id="agree" value="1" checked="checked" /> By clicking join you confirm that you accept our <a href="/privacy.html">Privacy Policy</a> and <a href="/terms.html">Terms of Service</a>.</label>
                <input class="btn btn-primary" type="submit" name="create" value="Join"/>
                <a href="/"><button type="button" class="btn">Cancel</button></a>
            </fieldset>
        </form>

That is my form using twitter bootstrap and validating it on the js side. However, not sure what is support to go in the action.

The page is being served by node.js through my router.

<code>
exports.signUp = function(req, res){
  res.render('signUp');
};

That is located in the routes folder and being called as a require('./routes/home.js) on my server.js file.

I have mongoose as a dependency in the package.json file and have tried to find more documentation on it which is pretty confusing.

My view engine is using html (not jade or ejs) although I am willing to use either, they are pretty easy to understand.

I am running mongo straight from my computer but was looking into mongohq to make things a bit easier.

Basically if anyone can help or give me direction for how to go about completing the form so the information can be put (POST) into a db in mongo and then pulled out of mongo (GET) and served onto a page as a user profile.

Another thing that I might need clarification on is how to go about GET-ting it to show on a new page such as My Profile Page (do I have to create a template/page or how do I link the info saved for creating an account to a My Profile page).

A guide through a whole form process from client-side to server-side including POST(the form) and GET(to a new page), using HTML, JS (jQuery, JSON), Node.Js, and Mongodb.


UPDATE

So here I have tried this for the POST, so now it is working, but getting an can't find html module error.

Here is my code for my server.js file.

<code>
  var express = require('express')
  , home = require('./routes/home.js')
  , path = require('path')
  , http = require('http')
  , mongoose = require('mongoose');

 mongoose.connect('mongodb://localhost/test');


app.post('/signUp', home.signUpUser);

---- Now this is my home.js (aka router js file)

<code>
var mongoose = require('mongoose');

var conn = mongoose.connection;
exports.index = function(req, res){
  res.render('index');
};

exports.signUp = function(req, res){
  res.render('signUp');
};

exports.about = function(req, res) {
    res.render('about');
};


exports.signUpUser = function (req, res, next) {
if (req.body && req.body.email && req.body.password === req.body.confirmPassword) {
    var obj = {
        firstName: req.body.firstName || 'na',
        lastName: req.body.lastName || 'na',
        email: req.body.email,
        password: req.body.password,
        phone: req.body.phoneNumber || '555-555-555',
        birthday: new Date(req.body.birthday) || new Date()
    };
    conn.collection('users').insert(obj, function (err) {
        if (!err) {
            res.redirect('/about.html');
        } else {
            next(err);
        }
    });
} else {
    next(new Error('Incorrect POST'));
}
};

In your form the "action" is the url the request should be made so for example action="/signup" .

I'm presuming you're using express in you example (from the res.render call).

With express you need to add the bodyParser middleware to your middlewarestack with: app.use(express.bodyParser());

After this you need a route for the post: app.post('/signup', routes.postedSignup);

The routes.postedSignup could look something like this:

exports.postedSignup = function (req, res, next) {
    if (req.body && req.body.email && req.body.password === req.body.confirmPassword) {
        var obj = {
            firstName: req.body.firstName || 'na',
            lastName: req.body.lastName || 'na',
            email: req.body.email,
            password: bcrypt.hashSync(req.body.password, 8),
            phone: req.body.phoneNumber || '555-555-555',
            birthday: new Date(req.body.birthday) || new Date()
        };
        db.userCollection.insert(obj, function (err) {
            if (!err) {
                res.redirect('/login');
            } else {
                next(err);
            }
        });
    } else {
        next(new Error('Incorrect POST'));
    }
};

Here the db should be your database driver and bcrypt is the bcrypt module for hashing the passwords with a random salt.

To get this data from your db, you'd create a route for it: app.get('/profile/:email', routes.getProfile);

This route would then look something like this (it's presuming the user is logged in and there's a valid session and the users data saved as req.session.user ):

exports.getProfile = function (req, res, next) {
    if (req.session.user && req.session.user.email === req.params.email || req.session.user.admin) {
        db.userCollection.findOne({ email: req.params.email }, function (err, result) {
            if (!err && result) {
                res.locals.user = result;
                res.render('userprofile');
            } else {
                var errorMessage = err || new Error('no user found');
                next(errorMessage);
            }
        });
    } else {
        next(new Error('Insufficient permissions'));
    }
};

For the data from res.locals.user to be usable, you need to use some kind of template to inject the data on res.render . Any values set to res.locals (or passed into the render call as an object), will be usable in the template, in this case the var you'd access would be called user .

The next() calls deliver the errors to the errorhandler, which i'm presuming you have in your middlewares as the last one. If not, you should read about it here .

You could also handle the situation with a client-side template, so you'd only return json from your routes, and not render any templates. For that you'd just replace res.render with res.json and the template name with the object you wish to send as json.

For a real-world application you'd have to flesh this out some more, for example checking that there's no user already with the same email etc. The signup could be separated into couple different functions so the other function could be reused for editing user profiles.

Also include express.csrf to your middlewares to protect the users from csrf attacks.

Hopefully this will get you going.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM