Node.js基于Express框架搭建一个简单的注册登录Web功能

这个小应用使用到了node.js  bootstrap  express  以及数据库的操作 :使用mongoose对象模型来操作 mongodb

如果没了解过的可以先去基本了解一下相关概念~

 

首先注明一下版本,因为express因为版本的不同使用的方式也不同,我这算是目前最新的了吧

还没有装express的可以移步到 看看express框架的获取安装

 

1.简单地项目初始化

进入你的nodejs安装路径下边,如图,然后执行命令  express -e test  (这里把项目名设置为test)

出现如上图所示,看到install dependencies没有,它说如果你想安装依赖就先进入项目test目录,然后执行 npm install安装依赖模块。

那就开始吧,网络环境差的可能安装会出错..出现很长一大串一般就行了

如此一来,项目初始已经完成,可以运行一下项目 npm start 看是否正常。

 

 

ok 还算正常,下面先来基本分析一下生成的初始项目

之前  已经说过 

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

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

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

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

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

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

 

先来看看文件信息package.json  一般项目的主要信息都会在这里产生

复制代码

{
  "name": "test","version": "0.0.0","private": true,"scripts": {
    "start": "node ./bin/www"
  },"dependencies": {
    "body-parser": "~1.12.0","cookie-parser": "~1.3.4","debug": "~2.1.1","ejs": "~2.3.1","express": "~4.12.2","morgan": "~1.5.1","serve-favicon": "~2.2.0"
  }
}
复制代码

看看主文件 app.js   这是它的初始形式,这个模块还要继续导出给 bin文件夹下的www文件使用

复制代码

 1 var express = require('express');
 2 var path = require('path');
 3 var favicon = require('serve-favicon');
 4 var logger = require('morgan');
 5 var cookieParser = require('cookie-parser');
 6 var bodyParser = require('body-parser');
 7 
 8 var routes = require('./routes/index');
 9 var users = require('./routes/users');
10 
11 var app = express();
12 
13 // view engine setup
14 app.set('views',path.join(__dirname,'views'));
15 app.set('view engine','ejs');
16 
17 // uncomment after placing your favicon in /public
18 //app.use(favicon(__dirname + '/public/favicon.ico'));
19 app.use(logger('dev'));
20 app.use(bodyParser.json());
21 app.use(bodyParser.urlencoded({ extended: false }));
22 app.use(cookieParser());
23 app.use(express.static(path.join(__dirname,'public')));
24 
25 app.use('/',routes);
26 app.use('/users',users);
27 
28 // catch 404 and forward to error handler
29 app.use(function(req,res,next) {
30   var err = new Error('Not Found');
31   err.status = 404;
32   next(err);
33 });
34 
35 // error handlers
36 
37 // development error handler
38 // will print stacktrace
39 if (app.get('env') === 'development') {
40   app.use(function(err,req,next) {
41     res.status(err.status || 500);
42     res.render('error',{
43       message: err.message,44       error: err
45     });
46   });
47 }
48 
49 // production error handler
50 // no stacktraces leaked to user
51 app.use(function(err,next) {
52   res.status(err.status || 500);
53   res.render('error',{
54     message: err.message,55     error: {}
56   });
57 });
58 
59 
60 module.exports = app;
复制代码

www文件内容:这里拥有着http服务器的基本配置

复制代码

 1 #!/usr/bin/env node
 2 
 3 /**
 4  * Module dependencies.
 5  */
 6 
 7 var app = require('../app');
 8 var debug = require('debug')('test:server');
 9 var http = require('http');
10 
11 /**
12  * Get port from environment and store in Express.
13  */
14 
15 var port = normalizePort(process.env.PORT || '3000');
16 app.set('port',port);
17 
18 /**
19  * Create HTTP server.
20  */
21 
22 var server = http.createServer(app);
23 
24 /**
25  * Listen on provided port,on all network interfaces.
26  */
27 
28 server.listen(port);
29 server.on('error',onError);
30 server.on('listening',onListening);
31 
32 /**
33  * Normalize a port into a number,string,or false.
34  */
35 
36 function normalizePort(val) {
37   var port = parseInt(val,10);
38 
39   if (isNaN(port)) {
40     // named pipe
41     return val;
42   }
43 
44   if (port >= 0) {
45     // port number
46     return port;
47   }
48 
49   return false;
50 }
51 
52 /**
53  * Event listener for HTTP server "error" event.
54  */
55 
56 function onError(error) {
57   if (error.syscall !== 'listen') {
58     throw error;
59   }
60 
61   var bind = typeof port === 'string'
62     ? 'Pipe ' + port
63     : 'Port ' + port;
64 
65   // handle specific listen errors with friendly messages
66   switch (error.code) {
67     case 'EACCES':
68       console.error(bind + ' requires elevated privileges');
69       process.exit(1);
70       break;
71     case 'EADDRINUSE':
72       console.error(bind + ' is already in use');
73       process.exit(1);
74       break;
75     default:
76       throw error;
77   }
78 }
79 
80 /**
81  * Event listener for HTTP server "listening" event.
82  */
83 
84 function onListening() {
85   var addr = server.address();
86   var bind = typeof addr === 'string'
87     ? 'pipe ' + addr
88     : 'port ' + addr.port;
89   debug('Listening on ' + bind);
90 }
复制代码

再来介绍一下项目使用到的ejs模板,比如看看这个view里边的index.ejs (我们待会可以直接把它转为html,差不多的)

复制代码



  
    <%= title %>
    
  
  
    

<%= title %>

Welcome to <%= title %>

复制代码

<%= title %> 这就是ejs的使用范例,title的值通过路由routes文件夹下index.js代码传入(后面再谈)

 

好了,基本介绍了项目的初始情况

 

2.基于初始项目的改进-- 注册登录功能

 

设计如下:

一个初始界面(其实就是原始地址:比如 localhost:3000(index.html  路径为/ ) ,在初始界面选择登录或注册

跳进来之后会先跳进登录界面(login.html  路径为 /login),可以选择先注册(跳转 register.html  路径为/register)

跳进注册界面后就会跳进(register.html 路径为 /register),注册成功后就跳转登录界面(login.html  路径为 /login)

在登录界面登录成功后就跳转(home.html  路径为 /home). 在home这里还提供了注销的功能(无页面文件,它的路径为 /logout

如果浏览器直接输入localhost:3000/home  要先判断是否登录成功,未登录不允许进入

看到上诉,应该了解到:我们是通过一个路径,然后通过这个路径的解析,从而渲染出这个路径对应的模板文件,其中我们这里的模板文件为.html后缀的

 

首先展示一下基本界面形态:

 

然后先注册吧,点击注册

 

 

填入用户名密码,这里稍微设置了两次密码相同的判断,注册成功它会自动跳转登录界面

用mongoVUE看看数据的创建

那就登录吧,登录成功跳转home界面

注销吧,注销后清除session值,然后跳转到根路径

然后试一下浏览器直接进入 home路径? 浏览器地址输入  localhost:3000/home  回车, ok 它自动跳转到登录界面

 

 

 

 

好现在开始解析如何构建这个小项目:

因为我们直接使用了后缀名 .html ,所以我们要先修改一下ejs模板  ,再把原来views目录下模板文件后缀改成 .html

复制代码

var app = express();

// view engine setup
app.set('views','views'));
app.engine("html",require("ejs").__express); // or app.engine("html",require("ejs").renderFile);
//app.set("view engine","ejs");
app.set('view engine','html');


<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a title="复制代码">

<img src="https://www.jb51.cc/res/2019/04-01/23/51e409b11aa51c150090697429a953ed.gif" alt="复制代码">

其实就是加一句再改一句。 __express 和renderFile都可以, 不用管它是什么,它能那样用就行了

 

然后我们知道需要这些模板文件,那就创建它们吧

index.html    其中 <%= title %>使用到了模板  连接 直接使用了路由路径的方法

复制代码



  
    <%= title %>
    
    


        
<script type="text/javascript" src="javascripts/jquery.min.js"&gt;</script>
<script type="text/javascript" src="javascripts/bootstrap.min.js"&gt;</script>
<script type="text/javascript"&gt;
$(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';
            }
        }); 
    }
    });
});
复制代码

login.html   跟上面register.html原理差不多

复制代码



    <%= title %>
    


        
<script type="text/javascript" src="javascripts/jquery.min.js"&gt;</script>
<script type="text/javascript" src="javascripts/bootstrap.min.js"&gt;</script>
<script type="text/javascript"&gt;
$(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',status){ 
                if(status == 'success'){ 
                    location.href = 'home';
                }
            },status){ 
                if(status == 'error'){ 
                    location.href = 'login';
                }
            }
        });
    });
});
</script>
复制代码

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

复制代码



  
    <%= title %>