Node.js_express_中間件 middleware_登陸/註冊實例源代碼

靜態資源: javascript

都寫死了的資源,如 css,htmlcss

 

解析規則:html

全部路由中間件都在一個數組中,js 引擎會按照代碼前後順序添加路由中間件java

當請求發送到服務器時,服務器獲取當前的請求信息(請求方式、請求路由路徑)node

遍歷數組,找到第一個匹配請求路由路徑請求方式必須徹底一致)到的路由或者中間件,執行其回調函數web

意味着: 聲明多個同名路由時,始終解析第一個mongodb

若是沒找到,返回一個狀態碼爲 404 的響應, Cannot GET / xxx    或者  Cannot POST / xxx數據庫

 

中間件 middlewareexpress

當有多個路由作同一件事情,這時就會交給中間件去完成json

本質上就是一個函數 (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!'));
相關文章
相關標籤/搜索