最新讲解版本请查看
https://yangyongli.blog.csdn.net/article/details/114364791
项目
展示
链接
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>