(十二)我的项目性能的实现之文章评论和退出性能
- 创立评论汇合
- 判断用户是否登录,如果用户登录,再容许用户提交评论表单
- 在服务器端创立文章评论性能对应的路由
- 在路由申请处理函数中接管客户端传递过去的评论信息
- 将评论信息存储在评论汇合中
- 将页面重定向回文章详情页面
在文章详情页面路由中获取文章评论信息并展现在页面中
BLOG -- 源码目录 └── config -- 配置文件 └── middleware └── loginGuard.js └── model -- 数据库操作 └── comment.js ├── public -- 动态资源 └── route -- 路由 └── admin ├── login.js 登录 └── logout.js 退出 └── home ├── article.js 博客文章 └──comment.js 博客评论 └── home.js 博客 └── views -- 模板 └── home └── common └──header.art 公共头部模板 └── article.art 文章内容模板 └── app.js -- 创立网站服务
comment.js
- 引入mongoose模块,创立汇合规定
- 增加存储每篇文章的aid,关联文章汇合
- 存储uid评论的用户名,关联用户汇合
- 存储评论工夫,内容time content
- 创立评论联合并作为模块成员进行导出
// 将评论汇合构造函数进行导入const { Comment } = require('../../model/comment'); module.exports = async (req, res) => { // 接管客户端传递过去的申请参数 const { content, uid, aid } = req.body; // 将评论信息存储到评论汇合中 await Comment.create({ content: content, uid: uid, aid: aid, time: new Date() }); // 将页面重定向回文章详情页面 res.redirect('/home/article?id='+ aid);}
login.js
- 对用户进行权限治理,治理能够去后盾,一般的跳转到博客首页
- userinfo示意用户是否登录
// 导入用户汇合构造函数const { User } = require('../../model/user');const bcrypt = require('bcrypt');module.exports = async (req, res) => { // 接管申请参数 const {email, password} = req.body; // 如果用户没有输出邮件地址 // if (email.trim().length == 0 || password.trim().length == 0) return res.status(400).send('<h4>邮件地址或者明码谬误</h4>'); if (email.trim().length == 0 || password.trim().length == 0) return res.status(400).render('admin/error', {msg: '邮件地址或者明码谬误'}); // 依据邮箱地址查问用户信息 // 如果查问到了用户 user变量的值是对象类型 对象中存储的是用户信息 // 如果没有查问到用户 user变量为空 let user = await User.findOne({email}); // 查问到了用户 if (user) { // 将客户端传递过去的明码和用户信息中的明码进行比对 // true 比对胜利 // false 比照失败 let isValid = await bcrypt.compare(password, user.password); // 如果明码比对胜利 if ( isValid ) { // 登录胜利 // 将用户名存储在申请对象中 req.session.username = user.username; // 将用户角色存储在session对象中 req.session.role = user.role; // res.send('登录胜利'); req.app.locals.userInfo = user; // 对用户的角色进行判断 if (user.role == 'admin') { // 重定向到用户列表页面 res.redirect('/admin/user'); } else { // 重定向到博客首页 res.redirect('/home/'); } } else { // 没有查问到用户 res.status(400).render('admin/error', {msg: '邮箱地址或者明码谬误'}) } } else { // 没有查问到用户 res.status(400).render('admin/error', {msg: '邮箱地址或者明码谬误'}) }}
loginGuard.js
- 把用户角色也存储在session中,如果用户是登录状态就让它跳转到博客首页,这样间接在url进行批改也不能够
const guard = (req, res, next) => { // 判断用户拜访的是否是登录页面 // 判断用户的登录状态 // 如果用户是登录的 将申请放行 // 如果用户不是登录的 将申请重定向到登录页面 if (req.url != '/login' && !req.session.username) { res.redirect('/admin/login'); } else { // 如果用户是登录状态 并且是一个普通用户 if (req.session.role == 'normal') { // 让它跳转到博客首页 阻止程序向下执行 return res.redirect('/home/') } // 用户是登录状态 将申请放行 next(); }}module.exports = guard;
article.art
- 在文章评论处模板语法如果是登录状态则显示
- 如果不是则暗藏评论表单
- 为评论表单增加申请地址action和申请形式method和name属性暗藏域hidden,一个蕴含登录用户的id值uid,一个是文章的id值aid,进行原文输入
- 对于评论人的信息进行循环动静输入,工夫格局的解决dateFormate
{{extend './common/layout.art'}}{{block 'link'}} <link rel="stylesheet" href="/home/css/article.css">{{/block}}{{block 'main'}} {{include './common/header.art'}} <!-- 文章框架开始 --> <div class="article"> <div class="w1100"> <div class="container"> <div class="article-header"> <h3 class="article-title">{{article.title}}</h3> <div class="article-info"> <span class="author">{{article.author.username}}</span> <span>{{dateFormat(article.publishDate, 'yyyy-mm-dd')}}</span> </div> </div> <div class="article-content"> {{@article.content}} </div> <div class="article-comment"> {{if userInfo}} <h4>评论</h4> <form class="comment-form" action="/home/comment" method="post"> <textarea class="comment" name="content"></textarea> <input type="hidden" name="uid" value="{{@userInfo._id}}"> <input type="hidden" name="aid" value="{{@article._id}}"> <div class="items"> <input type="submit" value="提交"> </div> </form> {{else}} <div><h2>先进行登录,再对文章进行评论</h2></div> {{/if}} <div class="comment-list"> {{each comments}} <div class="mb10"> <div class="article-info"> <span class="author">{{$value.uid.username}}</span> <span>{{dateFormat($value.time, 'yyyy-mm-dd')}}</span> <span>{{$value.uid.email}}</span> </div> <div class="comment-content"> {{$value.content}} </div> </div> {{/each}} </div> </div> </div> </div> </div> <!-- 文章框架完结 -->{{/block}}
logout.js
- 对用户userinfo进行革除,否则退出之后只是删除了cookie和session,userinfo还是存在的
- 实现退出性能,删除session 和cookie clearCookie(
- 并且重定向到用户登录页面
module.exports = (req, res) => { // 删除session req.session.destroy(function () { // 删除cookie res.clearCookie('connect.sid'); // 重定向到用户登录页面 res.redirect('/admin/login'); // 革除模板中的用户信息 req.app.locals.userInfo = null; });}
home.js
- 增加评论性能路由
// 援用expess框架const express = require('express');// 创立博客展现页面路由const home = express.Router();// 博客前台首页的展现页面home.get('/', require('./home/index'));// 博客前台文章详情展现页面home.get('/article', require('./home/article'));// 创立评论性能路由home.post('/comment', require('./home/comment'));// 将路由对象做为模块成员进行导出module.exports = home;
comment.js
- 承受到客户端传过来的申请信息
- 通过对象解构的模式获取
- 将评论汇合构造函数进行导入
- 将评论信息存储到评论汇合中,异步
- 将页面重定向回文章详情页面
// 将评论汇合构造函数进行导入const { Comment } = require('../../model/comment'); module.exports = async (req, res) => { // 接管客户端传递过去的申请参数 const { content, uid, aid } = req.body; // 将评论信息存储到评论汇合中 await Comment.create({ content: content, uid: uid, aid: aid, time: new Date() }); // 将页面重定向回文章详情页面 res.redirect('/home/article?id='+ aid);}
article.js
- 导入评论汇合构造函数
- 查问以后文章所对应的评论信息,用户名要多集联结查问populate
- 对文章和评论进行渲染
// 导入文章汇合构造函数const { Article } = require('../../model/article');// 导入评论汇合构造函数const { Comment } = require('../../model/comment');module.exports = async (req, res) => { // 接管客户端传递过去的文章id值 const id = req.query.id; // 依据id查问文章详细信息 let article = await Article.findOne({_id: id}).populate('author'); // 查问以后文章所对应的评论信息 let comments = await Comment.find({aid: id}).populate('uid') // res.send('欢送来到博客文章详情页面') res.render('home/article.art', { article, comments });
header.art
- 对于退出登录增加href
<!-- 头部 --><div class="header"> <!-- 网站标记 --> <div class="logo fl"> 黑马程序员 <i>ITHEIMA</i> </div> <!-- /网站标记 --> <!-- 用户信息 --> <div class="info"> <div class="profile dropdown fr"> <span class="btn dropdown-toggle" data-toggle="dropdown"> {{userInfo && userInfo.username}} <span class="caret"></span> </span> <ul class="dropdown-menu"> <li><a href="user-edit.html">个人资料</a></li> <li><a href="/admin/logout">退出登录</a></li> </ul> </div> </div> <!-- /用户信息 --></div><!-- /头部 -->
app.js
- 在用户未登录状况下,不会初始化一个cookie,saveUninitialized: false
- 给cookie设置一个主动过期的工夫
// 援用expess框架const express = require('express');// 解决门路const path = require('path');// 引入body-parser模块 用来解决post申请参数const bodyPaser = require('body-parser');// 导入express-session模块const session = require('express-session');// 导入art-tempate模板引擎const template = require('art-template');// 导入dateformat第三方模块const dateFormat = require('dateformat');// 导入morgan这个第三方模块const morgan = require('morgan');// 导入config模块const config = require('config');// 创立网站服务器const app = express();// 数据库连贯require('./model/connect');// 解决post申请参数app.use(bodyPaser.urlencoded({extended: false}));// 配置sessionapp.use(session({ secret: 'secret key', saveUninitialized: false, cookie: { maxAge: 24 * 60 * 60 * 1000 }}));// 通知express框架模板所在的地位app.set('views', path.join(__dirname, 'views'));// 通知express框架模板的默认后缀是什么app.set('view engine', 'art');// 当渲染后缀为art的模板时 所应用的模板引擎是什么app.engine('art', require('express-art-template'));// 向模板外部导入dateFormate变量template.defaults.imports.dateFormat = dateFormat;// 凋谢动态资源文件app.use(express.static(path.join(__dirname, 'public')));console.log(config.get('title'))// 获取零碎环境变量 返回值是对象 if (process.env.NODE_ENV == 'development') { // 以后是开发环境 console.log('以后是开发环境') // 在开发环境中 将客户端发送到服务器端的申请信息打印到控制台中 app.use(morgan('dev'))} else { // 以后是生产环境 console.log('以后是生产环境')}// 引入路由模块const home = require('./route/home');const admin = require('./route/admin');// 拦挡申请 判断用户登录状态app.use('/admin', require('./middleware/loginGuard'));// 为路由匹配申请门路app.use('/home', home);app.use('/admin', admin);app.use((err, req, res, next) => { // 将字符串对象转换为对象类型 // JSON.parse() const result = JSON.parse(err); // {path: '/admin/user-edit', message: '明码比对失败,不能进行用户信息的批改', id: id} let params = []; for (let attr in result) { if (attr != 'path') { params.push(attr + '=' + result[attr]); } } res.redirect(`${result.path}?${params.join('&')}`);})// 监听端口app.listen(80);console.log('网站服务器启动胜利, 请拜访localhost')