博客管理与文章发布系统-第三方模块及其用法Part2

上一篇写到了模板引擎的一些事,接着来看看下一个,在这之前补充一下路由模块的一些功能。

二级路由的使用。

//引入路由模块
const home = require('./route/home.js');
const admin = require('./route/admin.js');
//为路由匹配请求路径
app.use('/admin', admin);
app.use('/home', home);

区别了不同功能的同名请求,把app.use第一个参数作为对象的匹配路径,将二级路径的名字写在后方。

我们把二级路径的中间件统一放在route文件夹中,这里展示一些home部分的代码

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;

把二级路由的功能js存储在route文件夹下的home中,

其他:

res.render(返回渲染过的模板)

app.get('/index', (req, res) => {
    // 1.拼接模板路径
    // 2.拼接模板后缀
    // 3.哪一个模板和哪一个数据进行拼接
    // 4.将拼接结果响应给客户端
    res.render('index', {
        msg: 'message'
    });
})

app.locals

将某些属性挂在app.locals下,可以导入所有的模板文件中,比如用户进行登录了之后,就把用户的信息挂在app.locals下

示例:

        if (email == user.email || password == user.password) {
            req.session.username = user.username;
            //将用户的角色储存在session中
            req.session.role = user.role;
            // req.app拿到的就是app.js里面的app
            req.app.locals.userInfo = user;

这里的session后面再讲使用方法.

当表单提交的文件中有客户端上传的文件的时候,我们要用另一个模块来获取参数

//引入formidable第三方模块
// bodyParser无法解析文件上传的二进制代码我们选择formidable

//1.创建表单解析对象 //2.配置上传文件的存放位置 //3.保留上传文件的后缀(默认是不保留的) //4. 解析表单 //fields保存着普通的表单数据(除了二进制以外的), //files保存着上传的文件数据 const formidable = require('formidable'); const { Article } = require('../../model/article'); const path = require('path'); module.exports = (req, res) => { var form = new formidable.IncomingForm(); form.uploadDir = path.join(__dirname, '../', '../', 'public', 'uploads'); form.keepExtensions = true; form.parse(req, async(err, fields, files) => { await Article.create({ title: fields.title, author: fields.author, publishData: fields.publishData, cover: files.cover.path.split('public')[1], content: fields.content }); res.redirect('/admin/article'); }) }

 

form表单的标签中我们需要添加

enctype="multipart/form-data"否则无法正常使用该模块
 

 

 

一.用户注册相关

1.joi验证规则:

//验证用户信息
const joi = require('joi');

const validateUser = user => { const schema = { username: joi.string().min(2).max(12).required().error(new Error('用户名不符合验证规则')), email: joi.string().email().required().error(new Error('邮箱不符合验证规则')), password: joi.string().regex(/^[a-zA-Z0-9]{3,30}$/).required().error(new Error('密码不符合验证规则')), role: joi.string().valid('normal', 'admin').required().error(new Error('角色值非法')), state: joi.number().valid(1, 0).required().error(new Error('状态值非法')) }; return joi.validate(user, schema); } module.exports = { // User: User User, validateUser: validateUser };

解释:string()类型,min()长度最小值 required(是否必要) error(new Error(出错时的报错信息),.regex(正则表达式规则),必须是xx与yy中的一个valid(xx,yy).这里我们放出原始方法的代码对比一下,

注意:这里的是之前练习写的一段代码,与上一段无关。

const articalScheam = new mongoose.Schema({
    title:{
        type:String,
        // required:true,是否必要
        // minlength,maxlength字面意思
        // 可以自定义报错信息
        required:[true,'请传入文章标题'],
        minlength:[2,'文章长度最小不能小于2'],
        maxlength:4,
        // 去除字符串两侧的空格
        trim:true
    },

    publishdate:{
        type:Date,
        // default默认
        default:Date.now
    },

    catagory:{
        type:String,
        // 使值只在指定的内容中挑选
        enum:{
            // enum错误信息自定义方法
            values:['html','css','javascript'],
            message:'内容不符合要求'
        }
    },

    author:{
        //validator自定义验证规则
        type:String,
        validate:{
            validator: v => {
            // 返回布尔值,如果是true则成功,false失败
                return v && v.length >= 4;
            },
            // 自定义错误信息
            message:'传入的值不符合验证规则'
        }
    }

JOI用来验证信息比较方便我们这里传回了 

joi.validate(user, schema);

try {
        await validateUser(req.body);
    } catch (ex) {
        // ex.message
        return res.redirect('/admin/user-edit?message=' + ex.message);
    };

同理joi在用户信息修改的时候也可引用。

try catch验证信息是否正确,错误的话直接传回错误信息,然后回到注册页面。

 

二.用户登录相关

const { User } = require('../../model/user');

module.exports = async(req, res) => {
    //接受请求参数
    // 需要用到第三方模块body-parser
    const { email, password } = req.body;
    //当客户端的js验证被禁用时,需要有服务端的验证
    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, password });

    if (user) {
        //将用户端传递的密码和用户信息密码进行比对
        if (email == user.email || password == user.password) {
            req.session.username = user.username;
            //将用户的角色储存在session中
            req.session.role = user.role;
            // req.app拿到的就是app.js里面的app
            req.app.locals.userInfo = user;
            //对用户的角色进行判断
            if (user.role == 'admin') {
                res.redirect('/admin/user');
            } else {
                res.redirect('/home/');
            }

            // res.end('ok');
            //重定向到用户列表页面
            res.redirect('/admin/user');
        }
    } else {
        //没查询到
        res.status(400).render('admin/error', { msg: '邮箱地址或者密码错误' });
    }

这里简单的写一下session的用法(原理就不在这说了)

引入第三方模块

const session = require('express-session');
// 配置session
app.use(session({ secret: 'secret key',
     saveUninitialized: false ,
    cookie:{
        maxAge: 24 * 60 * 60 * 1000
    }
}));
 if (email == user.email || password == user.password) {
            req.session.username = user.username;
            //将用户的角色储存在session中
            req.session.role = user.role;
            // req.app拿到的就是app.js里面的app
            req.app.locals.userInfo = user;

在登陆成功后,将用户信息挂在locals下,补充一点,即使这个时候js文件中没有导入app,但是我们可以通过req.app拿到这个locals

posted @ 2020-05-23 22:15  Dokom  阅读(231)  评论(0编辑  收藏  举报