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

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://