(黑马程序员)MongoDB + Express + art-template 项目实例-博客管理系统 第三页

本文主要是介绍(黑马程序员)MongoDB + Express + art-template 项目实例-博客管理系统 第三页,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2、项目功能实现

2.1 登录与退出功能

2.1.1、创建用户集合,初始化用户

1)连接数据库

在 model 目录下新建 connect.js 文件:

// 引入 mongoose 第三方模块
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost/blog', { useNewUrlParser: true, useUnifiedTopology: true}).then(() => console.log('数据库连接成功')).catch(() => console.log('数据库连接失败'))

在 app.js 文件中引用:

// 数据库连接
require('./model/connect');

在命令行工具中可以看到:

2)创建用户集合

在 model 目录下新建 user.js:

// 引入 mongoose 第三方模块
const mongoose = require('mongoose');
// 创建用户集合规则
const userSchema = new mongoose.Schema({username: {type: String,required: true,minlength: 2,maxlength: 20},email:{type: String,required: true,//  唯一性,保证邮箱地址在插入数据库时不重复unique: true},password: {type: String,required: true},// admin-超级管理员 normal-普通用户 role: {type: String,required: true},// 0:启用状态  1:禁用状态state: {type: Number,default: 0}
});
// 创建用户信息集合
const User = mongoose.model('User', userSchema);// 将用户信息集合作为模块成员进行导出
module.exports = {User
}

3)初始化用户

在 user.js 文件中创建测试用户:

// 引入 mongoose 第三方模块
const mongoose = require('mongoose');
// 创建用户集合规则
const userSchema = new mongoose.Schema({username: {type: String,required: true,minlength: 2,maxlength: 20},email:{type: String,required: true,//  唯一性,保证邮箱地址在插入数据库时不重复unique: true},password: {type: String,required: true},// admin-超级管理员 normal-普通用户 role: {type: String,required: true},// 0:启用状态  1:禁用状态state: {type: Number,default: 0}
});
// 创建用户信息集合
const User = mongoose.model('User', userSchema);User.create({username: 'itjoe',email: 'joe@163.com',password: '123456',role: 'admin',state: 0
}).then(() => {console.log('用户创建成功')
}).catch(() => {console.log('用户创建失败')
})// 将用户信息集合作为模块成员进行导出
module.exports = {User
}

在 app.js 文件中引用:

// 用户集合
require('./model/user');

这时在命令行工具中可以看到:用户创建成功

 打开 Compass 软件,可以看到 blog 数据库中有一个 users 集合:创建用户成功

然后把 app.js 中引入 user.js 的代码删除,并把 user.js 中创建用户部分的代码注释掉。

2.1.2、 为登录表单项设置请求地址、请求方式以及表单项name属性 

打开 login.art 文件,添加代码: 

<form action="/login" method="post"><input name="email" type="email" class="form-control" placeholder="请输入邮件地址"><input name="password" type="password" class="form-control" placeholder="请输入密码">

2.1.3.、当用户点击登录按钮时,客户端验证用户是否填写了登录表单

给表单添加 id:

<form action="/login" method="post" id="loginForm">

在页面下方添加表单的点击事件代码:

<script type="text/javascript">//为表单添加提交事件$('#loginForm').on('submit', function () {// 获取到表单中用户输入的内容,返回值是数组 // [{name: 'email', value:: '用户输入的内容'}]var f = $(this).serializeArray()console.log(f)//  阻止表单默认提交的行为return false;});
</script>

打开浏览器刷新页面,随便输入一些内容,可以看到控制台打印出的数组:刚输入的内容

继续修改代码:

<script type="text/javascript">function serializeToJson(form) {var result = {};// serializeArray() 获取到表单中用户输入的内容,返回值是数组 // [{name: 'email', value:: '用户输入的内容'}]var f = form.serializeArray();// 把数组转换为对象 {enail: 'zhangsan@163.com', password: '123456'}f.forEach(function(item) {result[item.name] = item.value;});return result;}      //为表单添加提交事件$('#loginForm').on('submit', function () {var result = serializeToJson($(this))console.log(result)//  阻止表单默认提交的行为return false;});
</script>

回到浏览器刷新页面,重新输入内容,可以看到控制台打印出的对象:

在一个真实项目中,对表单进行处理是很常见的操作,所以我们可以把这个方法变为公共的方法。

在 public - admin - js 目录下,新建 common.js 文件,把 serializeToJson 方法剪切过来:

function serializeToJson(form) {var result = {};// serializeArray() 获取到表单中用户输入的内容,返回值是数组 // [{name: 'email', value:: '用户输入的内容'}]var f = form.serializeArray();// 把数组转换为对象 {enail: 'zhangsan@163.com', password: '123456'}f.forEach(function(item) {result[item.name] = item.value;});return result;
}

 再在 login.art 文件中引入 common.js 文件:

<script src="/admin/js/common.js"></script>

刷新浏览器冲洗验证下方法是否可以正常使用。

我们还可以再骨架文件中引入 common.js 文件,打开 layout.art 文件:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="/admin/lib/bootstrap/css/bootstrap.min.css"><link rel="stylesheet" href="/admin/css/base.css">{{block 'link'}} {{/block}}
</head><body>{{block 'main'}} {{/block}}<script src="/admin/lib/jquery/dist/jquery.min.js"></script><script src="/admin/lib/bootstrap/js/bootstrap.min.js"></script><script src="/admin/js/common.js"></script>{{block 'script'}} {{/block}}
</body></html>

2.1.4.、如果其中一项没有输入,阻止表单提交

继续修改 login.art 文件中的 js 代码:

<script type="text/javascript">     //为表单添加提交事件$('#loginForm').on('submit', function () {var result = serializeToJson($(this))// 如果用户没有输入邮件地址if (result.email.trim().length == 0) {alert('请输入邮件地址');// 阻止程序向下执行return false;}// 如果用户没有输入密码if (result.password.trim().length == 0) {alert('请输入密码');// 阻止程序向下执行return false;}});
</script>

浏览器刷新页面,不输入内容就提交的话,会弹出提示信息。

2.1.5、 服务器端接收请求参数,验证用户是否填写了登录表单

把表单的请求地址改为:/admin/login

Express 中接收 post 请求参数需要借助第三方包 body-parser

在命令行工具中下载安装:

npm install body-parser

打开 app.js 文件,引入 body-parser 模块,并进行全局的配置:

// 引入 body-parser 模块,用来处理 post 请求参数
const bodyParser = require('body-parser');// 配置 body-parser 模块,处理 post 请求参数
app.use(bodyParser.urlencoded({ extended: false }));

extended: false 方法内部使用 querystring 模块处理请求参数的格式

extended: true 方法内部使用第三方模块 qs 处理请求参数的格式

然后重启启动服务器:nodemon app.js

打开 admin.js 文件,添加 /login 的 post 请求:

// 实现登录功能
admin.post('/login', (req, res) => {// 接收请求参数res.send(req.body);
});
// 先把请求参数显示到页面中看下效果

下面要对请求参数进行二次验证

2.1.6、 如果其中一项没有输入,为客户端做出响应,阻止程序向下执行

继续编辑下 admin.js 的代码:

// 实现登录功能
admin.post('/login', (req, res) => {// 接收请求参数const {email, password} = req.body;// 如果用户没有输入邮件地址或密码if (email.trim().length == 0 || password.trim().length == 0) {return res.status(400).send('<h4>邮件地址或密码错误</h4>')}
});

我们测试下,先把 login.art 文件下面的 js 代码注释掉,然后刷新浏览器,不填写信息直接提交,可以看到:服务器端的验证

可以把页面美化下,在 views 目录下新建 error.art 文件:

{{extend './common/layout.art'}}{{block 'main'}}<p class="bg-danger error">{{msg}}</p>
{{/block}}

然后修改下 admin.js 文件中的代码:

// 实现登录功能
admin.post('/login', (req, res) => {// 接收请求参数const {email, password} = req.body;// 如果用户没有输入邮件地址或密码if (email.trim().length == 0 || password.trim().length == 0) {// return res.status(400).send('<h4>邮件地址或密码错误</h4>')return res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})}});

刷新页面,重新提交下看效果。

下面我们在 error.art 文件中设置定时器,3秒后再跳回到 login 登陆页:

{{extend './common/layout.art'}}{{block 'main'}}<p class="bg-danger error">{{msg}}</p>
{{/block}}{{block 'script'}}<script type="text/javascript">setTimeout(function () {location.href = '/admin/login';}, 3000)</script>
{{/block}}

回到浏览器中刷新,OK,3秒后跳回到 login 登陆页了。

下面要根据客户端传递过来的邮箱地址,查询用户是否存在。如果用户不存在,则阻止程序继续向下执行,并为客户端做出响应,告知客户端邮箱地址或者密码错误;如果用户存在,则使用客户端传递过来的密码和从数据库中查询出来的用户信息中的密码,进行比对。若两者的密码一致,则表示登录成功;若不一致,则表示登录失败。

2.1.7、根据邮箱地址查询用户信息

继续编辑 admin.js 文件的登录功能代码:

// 导入用户集合构造函数
const { User } = require('../model/user');// 实现登录功能
admin.post('/login', async (req, res) => {。。。// 根据邮箱地址查询用户信息let user = await User.findOne({email: email.trim()})
});

2.1.8、如果用户不存在,为客户端做出响应,阻止程序向下执行

继续编辑 admin.js 文件的登录功能代码:

// 实现登录功能
admin.post('/login', async (req, res) => {。。。// 根据邮箱地址查询用户信息let user = await User.findOne({email: email.trim()})// 如果没有查询到用户,user 变量为空if (user != null) {// 查询到了用户} else {// 没有查询到用户res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})} 
});

2.1.9、如果用户存在,将用户名和密码进行比对

继续编辑 admin.js 文件的登录功能代码:

// 实现登录功能
admin.post('/login', async (req, res) => {。。。// 根据邮箱地址查询用户信息let user = await User.findOne({email: email.trim()})// 如果没有查询到用户,user 变量为空if (user != null) {// 查询到了用户,将客户端传递过来的密码与查询出用户信息中的密码进行比对if (password == user.password) {}else{}} else {// 没有查询到用户res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})} 
});

2.1.10、比对成功,用户登录成功

// 查询到了用户,将客户端传递过来的密码与查询出用户信息中的密码进行比对if (password == user.password) {//登录成功res.send('登录成功');}else{// 登录失败}

2.1.11、比对失败,用户登录失败

// 查询到了用户,将客户端传递过来的密码与查询出用户信息中的密码进行比对if (password == user.password) {//登录成功res.send('登录成功');}else{// 登录失败res.status(400).render('admin/error.art', {msg: '邮件地址或密码错误'})}

刷新浏览器,输入正确的邮件和密码,可以看到:

这篇关于(黑马程序员)MongoDB + Express + art-template 项目实例-博客管理系统 第三页的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/159476

相关文章

Maven项目中集成数据库文档生成工具的操作步骤

《Maven项目中集成数据库文档生成工具的操作步骤》在Maven项目中,可以通过集成数据库文档生成工具来自动生成数据库文档,本文为大家整理了使用screw-maven-plugin(推荐)的完... 目录1. 添加插件配置到 pom.XML2. 配置数据库信息3. 执行生成命令4. 高级配置选项5. 注意事

Linux lvm实例之如何创建一个专用于MySQL数据存储的LVM卷组

《Linuxlvm实例之如何创建一个专用于MySQL数据存储的LVM卷组》:本文主要介绍使用Linux创建一个专用于MySQL数据存储的LVM卷组的实例,具有很好的参考价值,希望对大家有所帮助,... 目录在Centos 7上创建卷China编程组并配置mysql数据目录1. 检查现有磁盘2. 创建物理卷3. 创

eclipse如何运行springboot项目

《eclipse如何运行springboot项目》:本文主要介绍eclipse如何运行springboot项目问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目js录当在eclipse启动spring boot项目时出现问题解决办法1.通过cmd命令行2.在ecl

SpringBoot项目Web拦截器使用的多种方式

《SpringBoot项目Web拦截器使用的多种方式》在SpringBoot应用中,Web拦截器(Interceptor)是一种用于在请求处理的不同阶段执行自定义逻辑的机制,下面给大家介绍Sprin... 目录一、实现 HandlerInterceptor 接口1、创建HandlerInterceptor实

Maven项目打包时添加本地Jar包的操作步骤

《Maven项目打包时添加本地Jar包的操作步骤》在Maven项目开发中,我们经常会遇到需要引入本地Jar包的场景,比如使用未发布到中央仓库的第三方库或者处理版本冲突的依赖项,本文将详细介绍如何通过M... 目录一、适用场景说明​二、核心操作命令​1. 命令格式解析​2. 实战案例演示​三、项目配置步骤​1

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

Spring 缓存在项目中的使用详解

《Spring缓存在项目中的使用详解》Spring缓存机制,Cache接口为缓存的组件规范定义,包扩缓存的各种操作(添加缓存、删除缓存、修改缓存等),本文给大家介绍Spring缓存在项目中的使用... 目录1.Spring 缓存机制介绍2.Spring 缓存用到的概念Ⅰ.两个接口Ⅱ.三个注解(方法层次)Ⅲ.

一文教你Java如何快速构建项目骨架

《一文教你Java如何快速构建项目骨架》在Java项目开发过程中,构建项目骨架是一项繁琐但又基础重要的工作,Java领域有许多代码生成工具可以帮助我们快速完成这一任务,下面就跟随小编一起来了解下... 目录一、代码生成工具概述常用 Java 代码生成工具简介代码生成工具的优势二、使用 MyBATis Gen

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red

SpringBoot项目中Redis存储Session对象序列化处理

《SpringBoot项目中Redis存储Session对象序列化处理》在SpringBoot项目中使用Redis存储Session时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在Spri... 目录一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1