最新讲解版本请查看
https://yangyongli.blog.csdn.net/article/details/114364791


项目

展示

node.js 个人博客系统_Node.js

链接

https://download.csdn.net/download/weixin_45525272/15545983

GitHub今天上不去,就没往上发,过几天补上

实现

1. npm

npm init -y

npm install art-template blueimp-md5 body-parser bootstrap express express-art-template express-session jquery mongoose

2. 代码

app.js

var express = require('express')
var path = require('path')
var bodyParser = require('body-parser')
var session = require('express-session')
var router = require('./router')

var app = express();

app.use('/public/',express.static(path.join(__dirname,'./public')));
app.use('/node_modules/',express.static(path.join(__dirname,'./node_modules')));

// 模板引擎 art-template
app.engine('html',require('express-art-template'))
app.set('views',path.join(__dirname,'./views/'));

// 配置解析表单 POST 请求体插件(注意:一定要在 app.use(router) 之前 )
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())

app.use(session({
  // 配置加密字符串,它会在原有加密基础之上和这个字符串拼起来去加密
  // 目的是为了增加安全性,防止客户端恶意伪造
  secret: 'itcast',
  resave: false,
  saveUninitialized: false // 无论你是否使用 Session ,我都默认直接给你分配一把钥匙
}))

// 把路由挂载到 app 中
app.use(router);

app.listen(3000,function(){
    console.log('server is running.....');
})

router.js

var express = require('express');
// 数据库模块
var User = require('./models/user');    
var md5 = require('blueimp-md5');

var router = express.Router();

router.get('/',function(req,res){
    res.render('index.html',{
        user : req.session.user
    })
});


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

router.post('/login',function(req,res){
    var body= req.body;

    User.findOne({
        email: body.email,
        password: md5(md5(body.password))
    },function(err,user){
        if (err) {
             return res.status(500).json({
               err_code: 500,
               message: err.message
             })
         }
         // 如果邮箱和密码匹配,则 user 是查询到的用户对象,否则就是 null
        if(!user){
            return res.status(500).json({
                err_code : 1,
                message : '用户名或密码不正确 .'
            });
        }

        // 用户存在 登陆成功 通过 session 记录登陆状态
        req.session.user = user;

        res.status(200).json({
            err_code: 0,
            message: '登陆成功'
        });

    });
})



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

router.post('/register',function(req,res){
    // 1.获取表单数据
    var body = req.body;
    console.log("************************1************************* ");
    console.log(body);
    // 2.操作数据库
      //    判断改用户是否存在
      //    如果已存在,不允许注册
      //    如果不存在,注册新建用户
    User.findOne({
        $or: [
            {
                email:body.email
            },
            {
                nickname:body.nickname
            }
        ]
    },function(err,data){
        // 服务器错误
        console.log("************************2************************* ");
        if(err){
            return res.status(500).json({
                success: false,
                message: '服务端错误'
            });
        }

        // 判断改用户是否存在
        if (data) {
          // 邮箱或者昵称已存在
          return res.status(200).json({
            err_code: 1,
            message: 'Email or nickname aleady exists.'
          })
          return res.send(`邮箱或者昵称已存在,请重试`)
        }

        // 用户不存在 新建用户
        // 对密码进行 md5 加密
        body.password = md5(md5(body.password));

        new User(body).save(function(err,user){
            if(err){
                return res.status(500).json({
                  err_code: 500,
                  message: '注册失败.'
                })
            }
            // 注册成功,使用 Session 记录用户的登陆状态
            req.session.user = user;

            // 3.发送相应
            res.status(200).json({
              err_code: 0,
              message: 'OK'
            })

        });
    });  
    


});



// 个人信息 修改
router.get('/settings/profile', function (req, res) {
  res.render('./settings/profile.html',{
    user: req.session.user
  })
})

// 用户密码管理
router.get('/settings/admin',function(req,res){
  res.render('./settings/admin.html',{
    user: req.session.user
  })
})


router.get('/logout', function (req, res) {
  // 清除登陆状态
  req.session.user = null

  // 重定向到登录页
  res.redirect('/login')
})


module.exports = router;


user.js

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)

register.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>用户注册</title>
  <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css">
  <link rel="stylesheet" href="/public/css/login.css">
</head>

<body>
  <div class="main">
    <div class="header">
      <a href="/">
        <img src="/public/img/logo3.png" alt="" width="100px">
      </a>
      <h1>用户注册</h1>
    </div>
    <!-- 
      表单具有默认的提交行为,默认是同步的,同步表单提交,浏览器会锁死(转圈儿)等待服务端的响应结果。
      表单的同步提交之后,无论服务端响应的是什么,都会直接把响应的结果覆盖掉当前页面。

      后来有人想到了一种办法,来解决这个问题。
     -->
    <form id="register_form" method="post" action="/register">
      <div class="form-group">
        <label for="email">邮箱</label>
        <input type="email" class="form-control" id="email" name="email" placeholder="Email" autofocus>
      </div>
      <div class="form-group">
        <label for="nickname">昵称</label>
        <input type="text" class="form-control" id="nickname" name="nickname" placeholder="Nickname">
      </div>
      <div class="form-group">
        <label for="password">密码</label>
        <input type="password" class="form-control" id="password" name="password" placeholder="Password">
      </div>
      <button type="submit" class="btn btn-success btn-block">注册</button>
    </form>
    <div class="message">
      <p>已有账号? <a href="/login">点击登录</a>.</p>
    </div>
  </div>
  <script src="/node_modules/jquery/dist/jquery.js"></script>
  <script>
    $('#register_form').on('submit', function (e) {
      e.preventDefault()
      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.alert('注册成功!')
            // 服务端重定向针对异步请求无效
            window.location.href = '/'
          } else if (err_code === 1) {
            window.alert('邮箱已存在!')
          } else if (err_code === 2) {
            window.alert('昵称已存在!')
          } else if (err_code === 500) {
            window.alert('服务器忙,请稍后重试!')
          }
        }
      })
    })
  </script>
</body>

</html>

login.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>用户登录</title>
  <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css">
  <link rel="stylesheet" href="/public/css/login.css">
</head>

<body>
  <div class="main">
    <div class="header">
      <a href="/">
        <img src="/public/img/logo3.png" alt="" width="100px">
      </a>
      <h1>用户登录</h1>
    </div>
    <form id="login_form">
      <div class="form-group">
        <label for="">邮箱</label>
        <input type="email" class="form-control" id="" name="email" placeholder="Email" autofocus>
      </div>
      <div class="form-group">
        <label for="">密码</label>
        <a class="pull-right" href="">忘记密码?</a>
        <input type="password" class="form-control" id="" name="password" placeholder="Password">
      </div>
      <div class="checkbox">
        <label>
          <input type="checkbox">记住我
        </label>
      </div>
      <button type="submit" class="btn btn-success btn-block">登录</button>
    </form>
    <div class="message">
      <p>没有账号? <a href="/register">点击创建</a>.</p>
    </div>
  </div>
  <script src="/node_modules/jquery/dist/jquery.js"></script>
  <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) {
          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>
</body>

</html>