Node.js_express_中间件 middleware_登录/注册实例源代码

静态资源:

都写死了的资源,如 css,html

 

解析规则:

所有路由中间件都在一个数组中,js 引擎会按照代码先后顺序添加路由中间件

当请求发送到服务器时,服务器获取当前的请求信息(请求方式、请求路由路径)

遍历数组,找到第一个匹配请求路由路径请求方式必须完全一致)到的路由或者中间件,执行其回调函数

意味着: 声明多个同名路由时,始终解析第一个

如果没找到,返回一个状态码为 404 的响应, Cannot GET / xxx    或者  Cannot POST / xxx

 

中间件 middleware

当有多个路由做同一件事情,这时就会交给中间件去完成

本质上就是一个函数 (request, response, next)=>{}

express 框架 实现服务器    完全是由 路由 和 中间件 组成的

需要调用 next() 方法,才会接下来处理下面的中间件或者路由,否则卡住了

  • app.use(express.static('./public'));    //默认调用next

接受请求,通过分析参数,找到了 public 对应资源就返回响应

将该文件夹下所有静态资源暴露出去

例如: 文件夹有 

public/index.html

public/css/index.css

就可在浏览器访问

127.0.0.1:3000/index.html

127.0.0.1:3000/css/index.css

  • app.use(express.urlencoded({extended: true}));    //默认调用next

解析 请求体 数据,结果数据挂载到 req.body 上

  • 实例分析: 
  • // 1. 导入 express 模块
    const express =  require('express');
    
    // 2. 创建 app 应用对象
    const app = express();
    
    // 3. 写业务逻辑:处理请求,返回响应
    
              /**** 配置内置 中间件 (express 自带) ****/
        // 将该文件夹下所有静态资源暴露出去
    // 接受请求,通过分析参数,找到了
    public 对应资源就返回响应 app.use(express.static('./public')); // public 下有 index.html css/index.css // 可在127.0.0.1:3000/index.html css/index.css // 解析请求体数据,结果数据挂载到 req.body 上 app.use(express.urlencoded());
    // 默认调用 next() /**** 以上两个一般结合使用 ****/

    // 中间件默认能接收并处理所有请求
    // 需要调用 next() 方法,才会接下来处理下面的中间件或者路由,否则卡住了
    app.use((request, response, next)=>{
    next(); // 调用下一个中间件或者路由
    });
    /**************************************/
    // route 路由的组成: app.请求方式('/路由路径', 句柄函数); app.get('/login', (request, response)=>{ console.log(request.body); response.send('Login Page Response!'); }); app.post('/register', (request, response)=>{ console.log(request.query); response.send('Register Page Response!'); }); // 4. 监听端口号:一个端口号 有且只能运行 一个程序 app.listen(3000, err=>console.log(err?err:'服务器启动成功 : http://127.0.0.1:3000'));

 

登录/注册实例

  • 什么时候用 get ,什么时候用 post?

get 请求 只有 请求字符串,

post 请求 既有 请求字符串,又有 表单数据 form-data

1. 凡是涉及到用户的隐私数据,就用 post,相对安全

2. 其他就用 get

  • 业务逻辑

1. 导入 exoress 框架

2. 注册路由

由于默认访问不到静态资源,所以1引入中间件,暴露静态资源

默认不能解析 请求体 ,则2引入中间件,解析 请求体 数据(优先级低于上一中间件,避免多余分析)

获取用户提交的表单数据        req.body

对数据进行正则验证(验证数据的规范)    

检查用户名是否存在

连接数据库

User.findOne();

保存在数据库中        

User.create();

无论 失败/成功 都要返回

3. 登录路由

4. 设置端口号,启动服务器监听

  • 初次尝试,源代码

package.json

  • {
      "name": "node_express",
      "version": "1.0.0",
      "main": "index.js",
      "license": "MIT",
      "dependencies": {
        "express": "^4.16.4",
        "mongoose": "^5.4.0"
      }
    }

/route/register.html

  • <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8"/>
            <title>用户注册</title>
            
            <link rel="stylesheet" type="text/css" href="css/index.css"/>
        </head>
        
        <body>
            <div id="outer_box" class="register">
                <h2>用户注册</h2>
                <form action="http://localhost:3000/register" method="post">
                    <div class="clothes">
                        <label for="input_name">&nbsp;&nbsp;</label>
                        <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
                    </div>
            
                    <div class="clothes">
                        <label for="input_pwd">&nbsp;&nbsp;&nbsp;</label>
                        <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
                    </div>
                    
                    <div class="clothes">
                        <label for="input_repwd">确认密码</label>
                        <input id="input_repwd" type="password" name="user_repwd" placeholder="请再次输入密码" />
                    </div>
                    
                    <div class="clothes">
                        <label for="input_email">注册邮箱</label>
                        <input id="input_email" type="text" name="user_email" placeholder="请输入邮箱地址" />
                    </div>
                    
                    <div class="clothes">
                        <button class="register btn" type="submit">注册</button>
                        <a class="btn" href="http://localhost:3000/login">
                            <button type="button">登录</button>
                        </a>
                    </div>
                </form>
            </div>
            
            <script type="text/javascript" src="../index.js"></script>
        </body>
    </html>

/route/login.html

  • <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8"/>
            <title>用户登录</title>
            
            <link rel="stylesheet" type="text/css" href="css/index.css"/>
        </head>
        
        <body>
            <div id="outer_box" class="login">
                <h2>用户登录</h2>
                <form action="http://localhost:3000/login" method="post">
                    <div class="clothes">
                        <label for="input_name">&nbsp;&nbsp;</label>
                        <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
                    </div>
                    
                    <div class="clothes">
                        <label for="input_pwd">&nbsp;&nbsp;&nbsp;</label>
                        <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
                    </div>
                    
                    <div class="clothes">
                        <a class="btn" href="http://localhost:3000/register">
                            <button type="button">注册</button>
                        </a>
                        <button class="login btn" type="submit">登录</button>
                    </div>
                </form>
            </div>
            
        </body>
    </html>

/route/css/index.css

  • body {
        width: 100%;
        height: 100%;
        
        color: #000;
        background: #b9c2a4;
        background-size: cover; /* 指定背景图片大小 */
    }
    
    /*************************************************/
    #outer_box {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #1a45c3;
    }
    
    #outer_box.login {
        color: #9e098b;
    }
    
    #outer_box.register {
        color: #1a45c3;
    }
    
    #outer_box>h2{
        padding-bottom: 40px;
        margin-left: -50px;
    }
    
    .clothes {
        width: 260px;
        display: flex;
        justify-content: space-between;
        margin: 20px 0;
        font-size: 18px;
        line-height: 32px;
    }
    
    .clothes>label{
        width: 80px;
        text-align: center;
    }
    
    .clothes>input{
        width: 170px;
        height: 32px;
    }
    
    button {
        width: 100%;
        height: 100%;
        
        font-size: 16px;
        background-color: #c4ceda;
        cursor: pointer;
    }
    
    .clothes .btn{
        width: 64px;
        height: 32px;
        margin: 0 20px;
    }
    
    .clothes button.register{
        background-color: #1a45c3;
        color: #fff;
    }
    
    .clothes button.login{
        background-color: #9e098b;
        color: #fff;
    }

/db/connectDB.js

  • const mongoose = require('mongoose');
    
    const promiseConnect = new Promise((resolve, reject)=>{
        mongoose.connect('mongodb://localhost:27017/user_database', {useNewUrlParser:true})
        mongoose.connection.once('open', err=>{
            if(err){
                console.log(err);
                reject(err);
            }else{
                resolve(true);
            };
        });
    });
    
    module.exports = promiseConnect;

/db/tableModel.js

  • const mongoose = require('mongoose');
    
    const Schema = mongoose.Schema;
    const studentsSchema = new Schema({
        "userName": {
            "type": String,
            "default": "test"
        },
        "userPassword": {
            "type": String,
            "default": "123456"
        },
        "userEmail": {
            "type": String,
            "unique": true
        },
        "createTime": {
            "type": Date,
            "default": Date.now()
        }
    });
    
    const studentsModel = mongoose.model("user_info", studentsSchema);
    
    module.exports = studentsModel; 

index.js

  • const express =  require('express');
    const promiseConnect = require('./db/connectDB.js');
    const userInfoModel = require('./db/tableModel.js');
    
    promiseConnect.then(async result=>{
        if(result){
            isConeected = true;
        };
    }).catch(err=>console.log(err));
    
    const app = express();
    
    /*********************** 中间件 **********************/
    // 暴露路由 login.html register.html
    app.use(express.static('route'));    // 默认调用 next();
    
    // 将 用户输入的数据 挂载到 请求体 request.body  上
    app.use(express.urlencoded({extended: true}));    // 默认调用 next();
    
    /************************ get ***********************/
    app.get('/', (request, response)=>{
        response.redirect('./login.html');
    });
    
    app.get('/login', (request, response)=>{
        response.redirect('./login.html');
    });
    
    app.get('/register', (request, response)=>{
        response.redirect('./register.html');
    });
    
    /************************ post ***********************/
    
    let isConeected = false;
    let canBeCreated = false;
    let createSuccess = false;
    
    let logined = false;
    
    app.post('/register', async (request, response)=>{
        if(isConeected){
            let uName = request.body['user_name'];
            let uPwd = request.body['user_pwd'];
            let urePwd = request.body['user_repwd'];
            let uEmail = request.body['user_email'];
            userInfo = {
                "userName": uName,
                "userPassword": uPwd,
                "userEmail": uEmail
            };
            
            canBeCreated = false;
            createSuccess = false;
            someThingWrong = false;
            
            console.log('\n------------------注册--------------------');
            if(urePwd !== uPwd){
                console.log("(づ╥﹏╥)づ[两次输入不一致`]");
                response.redirect('./register.html');
                return ;
            }else if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
                console.log("(づ╥﹏╥)づ[用户名不合法`]");
                response.redirect('./register.html');
                return ;
            }else if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
                console.log("(づ╥﹏╥)づ[密码不合法`]");
                response.redirect('./register.html');
                return ;
            }else if(!(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(uEmail))){
                console.log('(づ╥﹏╥)づ[邮箱不合法`]');
                response.redirect('./register.html');
                return ;
            }else{
                canBeCreated = true;
                const badEmail = await userInfoModel.findOne({"userEmail": uEmail});
                if(badEmail){
                    console.log('(づ╥﹏╥)づ[邮箱已存在`]');
                    response.redirect('./register.html');
                    return ;
                };
            };
            
            const fond = await userInfoModel.findOne({"userName": uName});
            if(!fond && canBeCreated){
                await userInfoModel.create(userInfo);
                createSuccess = true;
                console.log('(o゜▽゜)o☆[注册成功!]☆');
            }else{
                console.log('(づ╥﹏╥)づ[用户名已存在`]');
            };
        };
        
        if(createSuccess){
            response.redirect('./login.html');
        }else{
            response.redirect('./register.html');
        };
    });
    
    app.post('/login',async (request, response)=>{
        if(isConeected){
            let uName = request.body['user_name'];
            let uPwd = request.body['user_pwd'];
            userInfo = {
                "userName": uName,
                "userPassword": uPwd
            };
        
            logined = false;
            
            console.log('\n------------------登录--------------------');
            if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
                logined = false;
                // 用户名不存在
            }else if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
                logined = false;
                // 密码错误
            };
            
            const findName = await userInfoModel.findOne({"userName": uName});
            const findPwd = await userInfoModel.findOne({"userPassword": uPwd});
            if(findName && findPwd){
                logined = true;
            };
        };
        
        console.log(logined?'(o゜▽゜)o☆[登录成功!]☆':'(づ╥﹏╥)づ[用户名或密码错误`]');
        response.redirect('./login.html');
    });
    
    /**************** 监听 3000, 启动服务器 ***************/
    app.listen(3000, err=>console.log(err?err:'\n\n服务器已启动: http://localhost:3000\nHunting Happy!'));

 


 

改进后,源代码

package.json

  • {
      "name": "node_express",
      "version": "1.0.0",
      "main": "index.js",
      "license": "MIT",
      "dependencies": {
        "express": "^4.16.4",
        "mongoose": "^5.4.0"
      }
    }

templates/login.html

  • <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8"/>
            <title>用户登录</title>
            
            <link rel="stylesheet" type="text/css" href="css/index.css"/>
        </head>
        
        <body>
            <div id="outer_box" class="login">
                <h2>用户登录</h2>
                <form action="http://localhost:3000/login" method="post">
                    <div class="clothes">
                        <label for="input_name">用&nbsp;户&nbsp;名</label>
                        <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
                    </div>
                    
                    <div class="clothes">
                        <label for="input_pwd">密&nbsp;&nbsp;&nbsp;码</label>
                        <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
                    </div>
                    
                    <div class="clothes">
                        <a class="btn" href="http://localhost:3000/register">
                            <button type="button">注册</button>
                        </a>
                        <button class="login btn" type="submit">登录</button>
                    </div>
                </form>
            </div>
        </body>
    </html>

templates/register.html

  • <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8"/>
            <title>用户注册</title>
            
            <link rel="stylesheet" type="text/css" href="css/index.css"/>
        </head>
        
        <body>
            <div id="outer_box" class="register">
                <h2>用户注册</h2>
                <form action="http://localhost:3000/register" method="post">
                    <div class="clothes">
                        <label for="input_name">用&nbsp;户&nbsp;名</label>
                        <input id="input_name" type="text" name="user_name" placeholder="请输入用户名" />
                    </div>
            
                    <div class="clothes">
                        <label for="input_pwd">密&nbsp;&nbsp;&nbsp;码</label>
                        <input id="input_pwd" type="password" name="user_pwd" placeholder="请输入密码" />
                    </div>
                    
                    <div class="clothes">
                        <label for="input_repeat_pwd">确认密码</label>
                        <input id="input_repeat_pwd" type="password" name="user_repeat_pwd" placeholder="请再次输入密码" />
                    </div>
                    
                    <div class="clothes">
                        <label for="input_email">注册邮箱</label>
                        <input id="input_email" type="text" name="user_email" placeholder="请输入邮箱地址" />
                    </div>
                    
                    <div class="clothes">
                        <button class="register btn" type="submit">注册</button>
                        <a class="btn" href="http://localhost:3000/login">
                            <button type="button">登录</button>
                        </a>
                    </div>
                </form>
            </div>
        </body>
    </html>

templates/css/index.css

  • @charset "utf-8";
    
    * {
        margin: 0px;
        padding: 0px;
    }
    
    .clearfix {
        zoom: 1;
    }
    
    .clearfix:before,
    .clearfix:after {
        content: "";
        display: table;
        clear: both;
    }
    
    .unSelectedAble {
        /* 内容不可以被选中 */
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
    }
    
    body {
        width: 100%;
        height: 100%;
        
        color: #000;
        background: #b9c2a4;
        background-size: cover; /* 指定背景图片大小 */
    }
    
    /*************************************************/
    #outer_box {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #1a45c3;
    }
    
    #outer_box.login {
        color: #9e098b;
    }
    
    #outer_box.register {
        color: #1a45c3;
    }
    
    #outer_box>h2{
        padding-bottom: 40px;
        margin-left: -50px;
    }
    
    .clothes {
        width: 260px;
        display: flex;
        justify-content: space-between;
        margin: 20px 0;
        font-size: 18px;
        line-height: 32px;
    }
    
    .clothes>label{
        width: 80px;
        text-align: center;
    }
    
    .clothes>input{
        width: 170px;
        height: 32px;
    }
    
    button {
        width: 100%;
        height: 100%;
        
        font-size: 16px;
        background-color: #c4ceda;
        cursor: pointer;
    }
    
    .clothes .btn{
        width: 64px;
        height: 32px;
        margin: 0 20px;
    }
    
    .clothes button.register{
        background-color: #1a45c3;
        color: #fff;
    }
    
    .clothes button.login{
        background-color: #9e098b;
        color: #fff;
    }

db/index.js

  • const mongoose = require('mongoose');
    
    module.exports = new Promise((resolve, reject)=>{
        mongoose.connect('mongodb://localhost:27017/user_database', {useNewUrlParser:true})
        mongoose.connection.once('open', err=>{
            if(err){
                console.log(err);
                reject(err);
            }else{
                resolve('数据库已连接');
            };
        });
    });

models/index.js

  • const mongoose = require('mongoose');
    
    const Schema = mongoose.Schema;
    const fieldSchema = new Schema({
        "userName": {
            "type": String,
            "unique": true,
            "required": true
        },
        "userPassword": {
            "type": String,
            "unique": true,
            "required": true
        },
        "userEmail": {
            "type": String,
            "unique": true,
            "required": true
        },
        "createTime": {
            "type": Date,
            "default": Date.now()
        }
    });
    
    module.exports = mongoose.model("user_info", fieldSchema);

index.js

  • const express =  require('express');
    const promiseConnect = require('./db');
    const userInfoModel = require('./models');
    
    const app = express();
    
    /*********************** 中间件 **********************/
    // 暴露路由 login.html register.html
    app.use(express.static('templates'));    // 默认调用 next();
    
    // 将 用户输入的数据 挂载到 请求体 request.body  上
    app.use(express.urlencoded({extended: true}));    // 默认调用 next();
    
    /************************ get ***********************/
    app.get('/', (request, response)=>{
        response.redirect('./login.html');
    });
    
    app.get('/login', (request, response)=>{
        response.redirect('./login.html');
    });
    
    app.get('/register', (request, response)=>{
        response.redirect('./register.html');
    });
    
    /************************ post ***********************/
    let logged = false ;
    promiseConnect.then(async result=>{
        console.log(result);
        
        app.post('/register', async (request, response)=>{
            const {
                user_name:uName,
                user_pwd:uPwd,
                user_repeat_pwd:urePwd,
                user_email:uEmail,
            } = request.body;    /**** 解构赋值 ****/
            // let uName = request.body['user_name'];
            // let uPwd = request.body['user_pwd'];
            // let urePwd = request.body['user_repeat_pwd'];
            // let uEmail = request.body['user_email'];
            userInfo = {
                "userName": uName,
                "userPassword": uPwd,
                "userEmail": uEmail
            };
            
            let errInfo = {};
            
            if(urePwd !== uPwd){
                errInfo.repeatPassword = '两次输入不一致';
            };
            if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
                errInfo.name = '用户名不合法';
            };
            if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
                errInfo.password = '密码不合法';
            };
            if(!(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(uEmail))){
                errInfo.email = '邮箱不合法';
            };
            
            const badEmail = await userInfoModel.findOne({"userEmail": uEmail});
            if(badEmail){
                errInfo.emailRegistered = '邮箱已被注册';
            };
            
            if(errInfo.repeatPassword || errInfo.name || errInfo.password || errInfo.email){
                response.send(errInfo);
                return;
            };
            
            const fond = await userInfoModel.findOne({"userName": uName});
            if(fond){
                response.send({"error":'用户名已被注册'});
            }else{
                await userInfoModel.create(userInfo);
                response.send({"success":'注册成功'});
            };
        });
        
        app.post('/login',async (request, response)=>{
            logged = false;
            let uName = request.body['user_name'];
            let uPwd = request.body['user_pwd'];
            userInfo = {
                "userName": uName,
                "userPassword": uPwd
            };
            
            if(!(/^[a-zA-Z][a-zA-Z0-9_]{5,20}$/.test(uName))){
                logged = false;    // 用户名不存在
            }else if(!(/^[a-zA-Z0-9_]{6,20}$/.test(uPwd))){
                logged = false;    // 密码错误
            };
            
            const findName = await userInfoModel.findOne({"userName": uName});
            const findPwd = await userInfoModel.findOne({"userPassword": uPwd});
            if(findName && findPwd){
                logged = true;
            };
            
            response.send(logged?{"success":'登录成功'}:{"error":'用户名或密码错误'});
        });
    }).catch(err=>console.log(err));
    
    /**************** 端口号 3000, 启动服务器 ***************/
    app.listen(3000, err=>console.log(err?err:'\n\n服务器已启动: http://localhost:3000\nHunting Happy!'));

 

posted @ 2018-12-21 17:46  耶梦加德  阅读(348)  评论(0编辑  收藏  举报