(黑马程序员)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

相关文章

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

springboot security验证码的登录实例

《springbootsecurity验证码的登录实例》:本文主要介绍springbootsecurity验证码的登录实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录前言代码示例引入依赖定义验证码生成器定义获取验证码及认证接口测试获取验证码登录总结前言在spring

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

SpringBoot项目启动报错"找不到或无法加载主类"的解决方法

《SpringBoot项目启动报错找不到或无法加载主类的解决方法》在使用IntelliJIDEA开发基于SpringBoot框架的Java程序时,可能会出现找不到或无法加载主类com.example.... 目录一、问题描述二、排查过程三、解决方案一、问题描述在使用 IntelliJ IDEA 开发基于

SpringBoot项目使用MDC给日志增加唯一标识的实现步骤

《SpringBoot项目使用MDC给日志增加唯一标识的实现步骤》本文介绍了如何在SpringBoot项目中使用MDC(MappedDiagnosticContext)为日志增加唯一标识,以便于日... 目录【Java】SpringBoot项目使用MDC给日志增加唯一标识,方便日志追踪1.日志效果2.实现步

Spring 中使用反射创建 Bean 实例的几种方式

《Spring中使用反射创建Bean实例的几种方式》文章介绍了在Spring框架中如何使用反射来创建Bean实例,包括使用Class.newInstance()、Constructor.newI... 目录1. 使用 Class.newInstance() (仅限无参构造函数):2. 使用 Construc