• 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('
      ------------------注册--------------------');
              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('
      ------------------登录--------------------');
              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:'
      
      服务器已启动: http://localhost:3000
      Hunting 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:'
      
      服务器已启动: http://localhost:3000
      Hunting Happy!'));

     

    --------小尾巴 ________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...
  • 相关阅读:
    Java后台插件(工具包)
    LINQ系列:Linq to Object联接操作符
    LINQ系列:Linq to Object排序操作符
    LINQ系列:Linq to Object限制操作符
    LINQ系列:Linq to Object投影操作符
    LINQ系列:C#中与LINQ相关特性
    设计模式笔记:简单工厂模式(Simple Factory)
    数据访问模式:数据并发控制(Data Concurrency Control)
    数据访问模式:Identity Map(标识映射)模式
    设计模式笔记:开闭原则(OCP,The Open-Closed Principle)
  • 原文地址:https://www.cnblogs.com/tianxiaxuange/p/10157205.html
Copyright © 2020-2023  润新知