登录注册------node.js基于express框架搭建---WEB功能

首先下载node,下载好后查看版本node -v

 

 【项目创建】对于express,其实有一种更普遍的方法,那就是直接用它来创建一个项目:

比如,我要创建项目express_test 就输入:express -e express_test

项目创建成功之后,生成4个文件夹,主文件app.js与配置信息文件packetage.json

①bin是项目的启动文件,配置以什么方式启动项目,默认 npm start

②public是项目的静态文件,放置js css img等文件

③routes是项目的路由信息文件,控制地址路由

④views是视图文件,放置模板文件ejs或jade等(其实就相当于html)

⑤express这样的MVC框架模式,是一个Web项目的基本构成

扫描二维码关注公众号,回复: 272359 查看本文章

【模块安装】:

一般我们创建新项目的时候也要先给他安装相应的模块

我们直接使用npm install 就行了,它会自动检测package.json文件下载安装相应的模块

之后可以先启动下项目:默认 npm start,启动成功后可以到浏览器查看下,或者自己修改----http://localhost:3000/

【最后】随手谈一下上面提到的require相关的知识

编写稍大一点的程序时一般都会将代码模块化,在NodeJS中,一般将代码合理拆分到不同的JS文件中,每一个文件就是一个模块,而文件路径就是模块名。

在编写每个模块时,都有require、exports、module三个预先定义好的变量可供使用。

(一)require函数用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象。

模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头),模块名中的.js扩展名可以省略

举个例子:var func1 = require("./func1");// 是与当前main.js同路径下的func1.js模块

(二)exports对象是当前模块的导出对象,用于导出模块公有方法和属性

别的模块通过require函数使用当前模块时得到的就是当前模块的exports对象

比如上面提到的,我们可以这样写代码然后导出来:

exports.func1 = function(){ 

    console.log("This is func1");

};

(三)module对象可以访问到当前模块的一些相关信息,但最多的用途是替换当前模块的导出对象(将导出对象改为函数)

例如模块导出对象默认是一个普通对象,如果想改成一个函数的话,可以使用以下方式。

func1.js:

module.exports = function () { 

     console.log('Hello World!');  

};

这样一来模块默认导出对象被替换为一个函数

//在func1.js里边这样

module.exports = function(name, age) { 

this.name = name; 

this.age = age; 

this.about = function() { 

console.log(this.name +' is '+ this.age +' years old')}}; 

//然后在main.js里边这样

var Func1 = require('./func1.js'); 

var r = new Func1('xiaoming', 12); 

r.about(); // xiaoming is 12 years old 

【解析小段node代码】:

var http = require('http');上面说到了,http是nodeJS里边内置的对象模块,我们使用require这种方式把它引进来

然后http现在这个对象模块有一个方法是http.createServer(),这个方法创建一个服务之后再监听一个地址:http.createServer().listen(port,ip)

从而搭建了一个服务器

createServer()里边有一个匿名函数,主要就是用来处理相关信息了。req是请求request,res是回复response。

req一般用于请求阶段的解析处理等,比如常见的get中的地址栏url字符的处理。res一般用于收到请求后相应的操作,比如写响应头响应体渲染页面等等。

在这里,res.writeHead(200, {'Content-Type': 'text/plain'});就相当于写了个响应头, res.end('Hello World\n');相当于写了个响应体。

nodeJS提供了很多内置对象方法,比如http,fs,EventEmitter,url等等

【构建项目】

(一)修改模板引擎文件:

现在开始解析如何构建这个小项目:直接使用了后缀名 .html ,所以我们要先修改一下ejs模板,再把原来views目录下模板文件后缀改成 .html

var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine("html",require("ejs").__express); 
//app.set("view engine","ejs");
app.set('view engine', 'html');

 (二)创建模板:error.html,home.html,index.html,login.html,register.html

其中 <%= title %>使用到了模板  连接<a> 直接使用了路由路径的方法,这里我的bootstrap引用的网上的,如果本地有的话可以调用本地

<h1><%= message %></h1>
<h2><%= error.status %></h2>
<pre><%= error.stack %></pre>

 user.name 就是使用ejs模板通过session.user来获取user对象,这里user有name和password的属性

<!DOCTYPE html>
<html>
<head>
    <title><%= title %></title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <style type="text/css">
        a{margin-left: 20px; text-decoration: none;}
        a:hover{text-decoration: underline;}
    </style>
</head>
<body>
<h1>Your name:   <%- user.name %></h1>
<p>Welcome to your home ~</p>
<p><a href="/logout">我要注销 </a>
</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <title><%= title %></title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <style type="text/css">
        a{margin-left: 20px; text-decoration: none;}
        a:hover{text-decoration: underline;}
    </style>
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>

<p><a href="/login">登录 </a>
    <a href="/register">   注册</a>
</p>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title><%= title %></title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <style type="text/css">
        .m15{ margin: 15px;}
        .tc{ text-align: center;font-size: 18px;font-weight: 600;}
    </style>
</head>
<body screen_capture_injected="true">
<div class="container">
    <%- message %>
    <form class="col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post" onsubmit="return false">
        <fieldset>
            <legend></legend>
            <div class="panel panel-default">
                <div class="panel-heading">
                    <p class="tc">请先登录</p>
                </div>
                <div class="panel-body m15">
                    <div class="form-group">
                        <div class="input-group">
                        <span class="input-group-addon">
                        <span class="glyphicon glyphicon-user"></span>
                        </span>
                            <input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名" required>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="input-group">
                        <span class="input-group-addon">
                        <span class="glyphicon glyphicon-lock"></span>
                        </span>
                            <input type="text" class="form-control" id="password" name="password" placeholder="请输入密码" required>
                        </div>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-primary btn-block" id="login0">登录</button>
                    </div>
                    <div class="form-group">
                        <button type="button" class="btn btn-info col-sm-2 col-sm-offset-10" id="register0">注册</button>
                    </div>
                </div>
            </div>
        </fieldset>
    </form>
</div>

<script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript">
    $(function(){
        $("#register0").click(function(){
            location.href = 'register';
        });
        $("#login0").click(function(){
            var username = $("#username").val();
            var password = $("#password").val();
            var data = {"uname":username,"upwd":password};
            $.ajax({
                url:'/login',
                type:'post',
                data: data,
                success: function(data,status){
                    if(status == 'success'){
                        location.href = 'home';
                    }
                },
                error: function(data,status){
                    if(status == 'error'){
                        location.href = 'login';
                    }
                }
            });
        });
    });
</script>
</body>
</head>
</html>

注册方式主要是把原始 form表单 onsubmit="return false" 防止默认提交,然后在输入信息正确的情况下,通过ajax,把表单信息post到路径/register

然后我们就通过路由功能根据此路径来处理信息

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title><%= title %></title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <style type="text/css">
        .m15{ margin: 15px;}
        .tc{ text-align: center;font-size: 18px;font-weight: 600;}
    </style>
</head>
<body screen_capture_injected="true">
<div class="container">
    <%- message %>
    <form class="col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post" onsubmit="return false">
        <fieldset>
            <legend></legend>
            <div class="panel panel-default">
                <div class="panel-heading">
                    <p class="tc">注册信息</p>
                </div>
                <div class="panel-body m15">
                    <div class="form-group">
                        <div class="input-group">
                        <span class="input-group-addon">
                        <span class="glyphicon glyphicon-user"></span>
                        </span>
                            <input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名" required>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="input-group">
                        <span class="input-group-addon">
                        <span class="glyphicon glyphicon-lock"></span>
                        </span>
                            <input type="text" class="form-control" id="password" name="password" placeholder="请输入密码" required>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="input-group">
                        <span class="input-group-addon">
                        <span class="glyphicon glyphicon-lock"></span>
                        </span>
                            <input type="text" class="form-control" id="password1" name="password1" placeholder="请再次输入密码" required>
                        </div>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-primary btn-block" id="register1">注册</button>
                    </div>
                    <div class="form-group">
                        <button type="button" class="btn btn-info col-sm-2 col-sm-offset-10" id="login1">登录</button>
                    </div>
                </div>
            </div>
        </fieldset>
    </form>
</div>

<script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript">
    $(function(){
        $("#login1").click(function(){
            location.href = 'login';
        });
        $("#register1").click(function(){
            var username = $("#username").val();
            var password = $("#password").val();
            var password1 = $("#password1").val();
            if(password !== password1){
                $("#password").css("border","1px solid red");
                $("#password1").css("border","1px solid red");
            }else if(password === password1){
                var data = {"uname":username,"upwd":password};
                $.ajax({
                    url: '/register',
                    type: 'post',
                    data: data,
                    success: function(data,status){
                        if(status == 'success'){
                            location.href = 'login';
                        }
                    },
                    error: function(data,err){
                        location.href = 'register';
                    }
                });
            }
        });
    });
</script>
</body>
</head>
</html>

(三)配置模板路由,让浏览器访问到路径后得以被解析

在app.js里添加路由配置

var express = require('express');
var routes = express.Router();
app.use('/', routes);  // 为路径 / 设置路由
app.use('/users', users); // 为路径 /users 设置路由
app.use('/login',routes); // 为路径 /login 设置路由
app.use('/register',routes); // 为路径 /register 设置路由
app.use('/home',routes); // 为路径 /home 设置路由
app.use("/logout",routes); // 为路径 /logout 设置路由

//app.use是一个中间件的用法,这里的routes看初始项目的下两句代码,就是引用了routes文件夹下的index.js模块
//var routes = require('./routes/index');
//var users = require('./routes/users');

 (四)创建项目数据库和超级管理员:

【操作数据库】数据库集合collection,文档设置insert

cmd命令行里:

mongo//进入数据库

use nodedb//创建项目数据库

db.addUser("shuaige", "123456")//给这个数据库创建了一个叫帅哥的账号,密码123456 (但是我觉得可能我理解的不到位,你也可以不做这个操作)

若以授权方式启动数据库,那么我们可以进行管理员验证,之后可以继续操作

然后,我们就为这个nodedb数据库创建collection(collection就相当于oracle和mysql里的table)

db.createCollection("users")//创建一个集合,也就是表
db.users.insert({user: "admin", password: "123456"})//给users里添加一个文档,也就是一条记录账号admin,密码123456

ok,现在检查一下:

db.users.find() //如果看到你刚刚添加的文档记录,就ok咯

 现在我的nodedb数据库里已经有了用户admin,之后操作就在nodedb数据库里进行

(五)连接数据库:

mongodb主要有两种使用方法,这里使用了其中的一种:使用 mongoose

Mongoose是MongoDB的一个对象模型工具,是基于node-mongodb-native开发的MongoDB nodejs驱动,可以在异步的环境下执行。

同时它也是针对MongoDB操作的一个对象模型库,封装了MongoDB对文档的的一些增删改查等常用方法,让NodeJS操作Mongodb数据库变得更加灵活简单

安装模块:npm i mongoose 

在项目根目录下建立一个database文件夹,建立文件models.js然后建立model处理文件 dbHandel.js

写入文件 models.js,一个user集合,有name和password属性

module.exports = { 
    user:{ 
        name:{type:String,required:true},
        password:{type:String,required:true}
    }
};

 写入文件 dbHandel.js  里边主要是获取 Schema 然后处理获取 model ,最后就是返回一个model了(提供其他文件对model的操作)

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var models = require("./models");
for(var m in models){ 
    mongoose.model(m,new Schema(models[m]));
}
module.exports = { 
    getModel: function(type){ 
        return _getModel(type);
    }
};
var _getModel = function(type){ 
    return mongoose.model(type);
};

 app.js加上连接数据库:

var mongoose = require('mongoose');
global.dbHandel = require('./database/dbHandel');
global.db = mongoose.connect("mongodb://localhost/nodedb");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
 app.js加上session模块,因为使用到了session(比如进入home的时候判断session值是否为空),所以需要express-session 模块   命令:npm i  express-session,在app.js中引用它并作初始设置
var session = require('express-session');
var app = express();
app.use(session({ 
    secret: 'secret'
    cookie:{ 
        maxAge: 1000*60*30
    }
}));

app.use(function(req,res,next){ 
    res.locals.user = req.session.user;   // 从session 获取 user对象
    var err = req.session.error;   //获取错误信息
    delete req.session.error;
    res.locals.message = "";   // 展示的信息 message
    if(err){ 
        res.locals.message = '<div class="alert alert-danger" style="margin-bottom:20px;color:red;">'+err+'</div>';
    }
    next();  //中间件传递
});

【好现在想想我们还剩下什么:】

数据库已经提供出model接口给我们使用(给它填数据)

已经初始化了路径处理

初始化了session信息 数据库配置等

页面模板也已经做完

所以剩下的就是路径处理的部分:去routes目录下修改index.js

  / 路径:

/* GET index page. */
router.get('/', function(req, res,next) {
  res.render('index', { title: 'Express' });    // 到达此路径则渲染index文件,并传出title值供 index.html使用
});

 /login 路径:

/* GET login page. */
router.route("/login").get(function(req,res){    // 到达此路径则渲染login文件,并传出title值供 login.html使用
    res.render("login",{title:'User Login'});
}).post(function(req,res){                        // 从此路径检测到post方式则进行post数据的处理操作
    //get User info
     //这里的User就是从model中获取user对象,通过global.dbHandel全局方法(这个方法在app.js中已经实现)
    var User = global.dbHandel.getModel('user');  
    var uname = req.body.uname;                //获取post上来的 data数据中 uname的值
    User.findOne({name:uname},function(err,doc){   //通过此model以用户名的条件 查询数据库中的匹配信息
        if(err){                                         //错误就返回给原post处(login.html) 状态码为500的错误
            res.send(500);
            console.log(err);
        }else if(!doc){                                 //查询不到用户名匹配信息,则用户名不存在
            req.session.error = '用户名不存在';
            res.send(404);                            //    状态码返回404
        //    res.redirect("/login");
        }else{ 
            if(req.body.upwd != doc.password){     //查询到匹配用户名的信息,但相应的password属性不匹配
                req.session.error = "密码错误";
                res.send(404);
            //    res.redirect("/login");
            }else{                                     //信息匹配成功,则将此对象(匹配到的user) 赋给session.user  并返回成功
                req.session.user = doc;
                res.send(200);
            //    res.redirect("/home");
            }
        }
    });
});

 /register 路径

/* GET register page. */
router.route("/register").get(function(req,res){    // 到达此路径则渲染register文件,并传出title值供 register.html使用
    res.render("register",{title:'User register'});
}).post(function(req,res){ 
     //这里的User就是从model中获取user对象,通过global.dbHandel全局方法(这个方法在app.js中已经实现)
    var User = global.dbHandel.getModel('user');
    var uname = req.body.uname;
    var upwd = req.body.upwd;
    User.findOne({name: uname},function(err,doc){   // 同理 /login 路径的处理方式
        if(err){ 
            res.send(500);
            req.session.error =  '网络异常错误!';
            console.log(err);
        }else if(doc){ 
            req.session.error = '用户名已存在!';
            res.send(500);
        }else{ 
            User.create({                             // 创建一组user对象置入model
                name: uname,
                password: upwd
            },function(err,doc){ 
                 if (err) {
                        res.send(500);
                        console.log(err);
                    } else {
                        req.session.error = '用户名创建成功!';
                        res.send(200);
                    }
                  });
        }
    });
});

  /home 路径:

/* GET home page. */
router.get("/home",function(req,res){ 
    if(!req.session.user){                     //到达/home路径首先判断是否已经登录
        req.session.error = "请先登录"
        res.redirect("/login");                //未登录则重定向到 /login 路径
    }
    res.render("home",{title:'Home'});         //已登录则渲染home页面
});

 /logout路径:

/* GET logout page. */
router.get("/logout",function(req,res){    // 到达 /logout 路径则登出, session中user,error对象置空,并重定向到根路径
    req.session.user = null;
    req.session.error = null;
    res.redirect("/");
});

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自570109268.iteye.com/blog/2384282
今日推荐