zoukankan      html  css  js  c++  java
  • node.js(node.js+mongoose小案例)_实现简单的注册登录退出

    一、前言                                                                                 

    通过node.js基本知识对node.js基本知识的一个简单应用

                                1、注册

                                2、登录

                                 3、退出                                                              

    二、基本内容                                                                         

    1、项目结构搭建如图所示

    2、这个小案列中用到了art-template子模板以及模板的继承 可以参考官网:art-template.org

         发现很多网站的页面的头部和尾部都是一样的,所以我们可以将头部和尾部提取出来,用art-template子模板,弄到一个单独页面中,其他页面继承这个页面

       

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>{{block 'title'}}默认标题{{/block}}</title>
      <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css">
     
      {{block 'head'}}{{/block}}
    </head>
    
    <body>
      {{include '../_partials/header.html'}} <!--用子模板引入头部-->
      {{block 'body'}}{{/block}}
      {{include '../_partials/footer.html'}}  <!--用子模板引入尾部-->
      <script src="/node_modules/jquery/dist/jquery.js"></script>
      <script src="/node_modules/bootstrap/dist/js/bootstrap.js"></script>
      {{block 'script'}}{{/block}}
    </body>
    
    </html>

    3、先安装依赖包快速搭建一个服务:

         express

        express-art-template     

        path :可以帮助我们操作路径,这里如果我们的项目放到别人的电脑上,如果用原来的方法就可能存在路径找不到的情况

        art-template

    var express  = require('express')
    //引入path包
    var path = require('path')
    var app = new express();
    
    //配置express-art-template
    app.engine('html', require('express-art-template'))
    
    //开放静态资源
    app.use('/public/', express.static(path.join(__dirname, './public/')))
    app.use('/node_modules/', express.static(path.join(__dirname, './node_modules/')))
    
    
    app.get('/', function (req, res){
       res.render('index.html')
    })
    
    app.listen(5000, function (){
        console.log('server')
    })

    4、设计路由

    路径

    方法

    Get参数

    Post参数

    是否需要登录

    备注

    /

    GET

    渲染首页

    /register

    GET

    渲染注册页

    /register

    POST

    Uername,password,nickname

    处理注册信息

    /login

    GET

    渲染登录页

    /login

    post

    Username,password

    处理登录请求

    /logout

    get

    退出登录

      5、将路由写在单独的一个模块里面

         (1)搭好路由壳子

    var express = require('express')
    
    var router = express.Router()
    //渲染首页
    router.get('/',function (req, res) {
    
    })
    
    //渲染注册页
    router.get('/register',function (req, res) {
    
    })
    //处理注册请求
    router.post('/register',function (req, res) {
    
    })
    //渲染登录页
    
    router.get('/login',function (req, res) {
    
    })
    //处理登录页
    router.post('/login',function (req, res) {
    
    })
    //退出
    router.get('/logout',function (req, res) {
    
    })
    
    //挂载导出
    module.exports = router

         (2)app.js中引入router.js

      

    //引入
    var router = require('./router')
    //使用
    app.use(router)

    6、设计mongose数据库模型

         (1)注册的时候需要用到mongodb数据库

          安装:cnpm install mongoose

          引入:var mongoose = require("mongoose")

          开启数据库:mongo

         (2)根据可能显示的用户信息设计数据库模型,并且将这个模型放到单独的一个models目录下面    

    var mongoose = require('mongoose')
    
    // 连接数据库
    mongoose.connect('mongodb://localhost/test', { useMongoClient: true })
    
    var Schema = mongoose.Schema
    
    var userSchema = new Schema({
      email: {
        type: String,
        required: true
      },
      nickname: {
        type: String,
        required: true
      },
      password: {
        type: String,
        required: true
      },
      created_time: {
        type: Date,
        // 注意:这里不要写 Date.now() 因为会即刻调用
        // 这里直接给了一个方法:Date.now
        // 当你去 new Model 的时候,如果你没有传递 create_time ,则 mongoose 就会调用 default 指定的Date.now 方法,使用其返回值作为默认值
        default: Date.now
      },
      last_modified_time: {
        type: Date,
        default: Date.now
      },
      avatar: {
        type: String,
        default: '/public/img/avatar-default.png'
      },
      bio: {
        type: String,
        default: ''
      },
      gender: {
        type: Number,
        enum: [-1, 0, 1],
        default: -1
      },
      birthday: {
        type: Date
      },
      status: {
        type: Number,
        // 0 没有权限限制
        // 1 不可以评论
        // 2 不可以登录
        enum: [0, 1, 2],
        default: 0
      }
    })
    
    module.exports = mongoose.model('User', userSchema)
    数据库模型

         (3)在router.js中引入数据库

     var User = require('./models/user')

    7、数据库模型设计好了之后处理注册事件

         注册响应主要包含以下几个逻辑

         (1)当用户发送get请求的时候会跳转到注册页面,

         (2)用户输入注册信息,输入的注册信息会和数据库中的信息进行查找对比

         (3)如果数据库中存在这个用户信息,则提示用户 “用户名已存在”

         (4)如果数据库中不存在这用户信息,则可以注册,并将信息保存在session中

         (5)注册完成之后页面跳到首页,并且在页面右上角显示用户名, 此时登录/注册按钮隐藏

        (1)点击注册的时候跳转到注册页面

    router.get('/register',function (req, res) {
      res.render('register.html')
    })

        

      (2)客户端发送ajax请求,

    $('#register-form').on('submit', function (e){
      //将提交的表单数据键值对序列化可以提交的字符串
       var formData = $(this).serialize()
    
       $.ajax({
       url: '/register',
       type: 'post',
       data: formData,
       dataType: 'json',
       success: function (data) {
       var err_code = data.err_code
       if(err_code === 0) {
           //如果注册成功,则进行表单重定向
           window.location.href('/')
    
          }else if(err_code === 1) {
           window.alert('邮箱已存在!')
    
          } else if (err_code === 500) {
                window.alert('服务器忙,请稍后重试!')
          }
        }
       })
    })

      (3)服务端接受到客户端提交过来的数据,将受到的数据到mongose数据库中查询

    router.post('/register', function (req,  res) {
       //保存收到的数据
       var body = req.body
       //查询
       User.findOne({
       
       $or: [
           { email: body.email},
           { nickname: body.nickname}
    
               ]
       }, function (err,  data) {
        
       //判断
       if(err) {
          //这里一定要响应json格式的字符串,客户端才收的到
          return res.status(500).json({
            success: false,
            message: "服务器出错"
          })
    
       }
    
       //如果查询到了,就提示邮箱或者昵称已经存在
       if(data) {
          
          return res.status(200).json({
         err_code: 1,
         message:"邮箱或者用户名已经存在"
        })
    
       }
    
       //执行到这里,不存在,就可以注册
       new User(body).save(function (err,  data) {
         if(err) {
              return res.status(500).json({
                          err_code: 500,
                         message: 'Internal error.'
               })
    
         }
    
         res.session.user = body;  //这里用express保存注册的信息
         return res.status(200).json({
                     err_code:0,
                    message: '注册成功'
                })
         })
      })
    })

    (4)注意点:ajax的dataType是json格式的, 如果服务端给我们响应的数据不是json格式,客户端就接受不到

                            express中提供了一个json()函数,会自动将字符串转化为json格式

                           这里用到了express-session,来保存用户信息

    5、登录

        服务端接收到了请求数据,然后在数据库中进行查询

    router.post('/login',function (req, res) {
       var body = req.body;
    
       //查找
       User.findOne({
           email: body.email,
           password: body.password},function (err, user){
         if(err) {
    
             return res.status(500).json({
                 err_code:500,
                 message: 'err'
             })
         }
    
         if(!user) {
             return res.status(200).json({
                 err_code: 1,
                 message: '邮箱或者密码错误'
             })
         }
         res.session.user = user  //记录此时的登录信息
         return res.status(200).json({
                 err_code: 0,
                 message: 'success'
             })
    
       })
    })

    客户端接受到了服务端的数据响应

    <script>
       $('#login_form').on('submit', function (e) {
    
          e.preventDefault()
          var formData = $(this).serialize()
          console.log(formData)
          $.ajax({
            url: '/login',
            type: 'post',
            data: formData,
            dataType: 'json',
            success: function (data) {
              console.log(data)
              var err_code = data.err_code;
    
              if (err_code === 0) {
                window.alert('登录成功')
               window.location.href='/'
              }else if (err_code === 1) {
                window.alert('邮箱或密码错误');
              }else if(err_code === 500){
                window.alert('服务繁忙,稍后请重试')
              }
            }
          })
        })
      </script>

    6、退出的时候只要清除session就可以

    //退出
    router.get('/logout',function (req, res) {
        req.session.user = null;
        res.redirect('/')
    })

        

    三、总结                                                                                         

    1、ajax中的dataType为json, 如果服务器响应的数据步数json格式的,在ajax中接受不到这个信息

    2、服务器默认只能重定向只针对同步请求有效, 对异步请求无效

     

    虽然现在走得很慢,但不会一直这么慢
  • 相关阅读:
    jquery点击tr换背景颜色
    poi导出excel
    Lua 可变参数 ... 的一点测试
    改写Unity DropDown 支持多次点击同一选项均回调
    g++ 生成C++ .so库文件,并调用示例
    Unity NavMesh 格式 解析 分析 对比 Recast Navigation
    SVN 问题解决之 Working copy path does not exist in repository
    SVN 问题解决之 The XML response contains invalid XML
    C++ DLL debug版本在其他PC上缺少依赖的处理方式
    Unity 宽度适配 NGUI
  • 原文地址:https://www.cnblogs.com/xxm980617/p/10575305.html
Copyright © 2011-2022 走看看