最新講解版本請查看
https://yangyongli.blog.csdn.net/article/details/114364791
項目
展示

鏈接
https://download.csdn.net/download/weixin_45525272/15545983
GitHub今天上不去,就沒往上發(fā),過幾天補(bǔ)上
實現(xiàn)
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({
// 配置加密字符串,它會在原有加密基礎(chǔ)之上和這個字符串拼起來去加密
// 目的是為了增加安全性,防止客戶端惡意偽造
secret: 'itcast',
resave: false,
saveUninitialized: false // 無論你是否使用 Session ,我都默認(rèn)直接給你分配一把鑰匙
}))
// 把路由掛載到 app 中
app.use(router);
app.listen(3000,function(){
console.log('server is running.....');
})
router.js
var express = require('express');
// 數(shù)據(jù)庫模塊
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 記錄登陸狀態(tài)
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.獲取表單數(shù)據(jù)
var body = req.body;
console.log("************************1************************* ");
console.log(body);
// 2.操作數(shù)據(jù)庫
// 判斷改用戶是否存在
// 如果已存在,不允許注冊
// 如果不存在,注冊新建用戶
User.findOne({
$or: [
{
email:body.email
},
{
nickname:body.nickname
}
]
},function(err,data){
// 服務(wù)器錯誤
console.log("************************2************************* ");
if(err){
return res.status(500).json({
success: false,
message: '服務(wù)端錯誤'
});
}
// 判斷改用戶是否存在
if (data) {
// 郵箱或者昵稱已存在
return res.status(200).json({
err_code: 1,
message: 'Email or nickname aleady exists.'
})
return res.send(`郵箱或者昵稱已存在,請重試`)
}
// 用戶不存在 新建用戶
// 對密碼進(jìn)行 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 記錄用戶的登陸狀態(tài)
req.session.user = user;
// 3.發(fā)送相應(yīng)
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) {
// 清除登陸狀態(tài)
req.session.user = null
// 重定向到登錄頁
res.redirect('/login')
})
module.exports = router;
user.js
var mongoose = require('mongoose')
// 連接數(shù)據(jù)庫
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() 因為會即刻調(diào)用
// 這里直接給了一個方法:Date.now
// 當(dāng)你去 new Model 的時候,如果你沒有傳遞 create_time ,則 mongoose 就會調(diào)用 default 指定的Date.now 方法,使用其返回值作為默認(rèn)值
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 沒有權(quán)限限制
// 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>
<!--
表單具有默認(rèn)的提交行為,默認(rèn)是同步的,同步表單提交,瀏覽器會鎖死(轉(zhuǎn)圈兒)等待服務(wù)端的響應(yīng)結(jié)果。
表單的同步提交之后,無論服務(wù)端響應(yīng)的是什么,都會直接把響應(yīng)的結(jié)果覆蓋掉當(dāng)前頁面。
后來有人想到了一種辦法,來解決這個問題。
-->
<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">點(diǎn)擊登錄</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('注冊成功!')
// 服務(wù)端重定向針對異步請求無效
window.location.href = '/'
} else if (err_code === 1) {
window.alert('郵箱已存在!')
} else if (err_code === 2) {
window.alert('昵稱已存在!')
} else if (err_code === 500) {
window.alert('服務(wù)器忙,請稍后重試!')
}
}
})
})
</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">點(diǎn)擊創(chuàng)建</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('注冊成功!')
// 服務(wù)端重定向針對異步請求無效
window.location.href = '/'
} else if (err_code === 1) {
window.alert('郵箱或者密碼錯誤')
} else if (err_code === 500) {
window.alert('服務(wù)器忙,請稍后重試!')
}
}
})
})
</script>
</body>
</html>