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

相关文章

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

在ASP.NET项目中如何使用C#生成二维码

《在ASP.NET项目中如何使用C#生成二维码》二维码(QRCode)已广泛应用于网址分享,支付链接等场景,本文将以ASP.NET为示例,演示如何实现输入文本/URL,生成二维码,在线显示与下载的完整... 目录创建前端页面(Index.cshtml)后端二维码生成逻辑(Index.cshtml.cs)总结

Java Stream流以及常用方法操作实例

《JavaStream流以及常用方法操作实例》Stream是对Java中集合的一种增强方式,使用它可以将集合的处理过程变得更加简洁、高效和易读,:本文主要介绍JavaStream流以及常用方法... 目录一、Stream流是什么?二、stream的操作2.1、stream流创建2.2、stream的使用2.

Spring Boot项目如何使用外部application.yml配置文件启动JAR包

《SpringBoot项目如何使用外部application.yml配置文件启动JAR包》文章介绍了SpringBoot项目通过指定外部application.yml配置文件启动JAR包的方法,包括... 目录Spring Boot项目中使用外部application.yml配置文件启动JAR包一、基本原理

Springboot项目登录校验功能实现

《Springboot项目登录校验功能实现》本文介绍了Web登录校验的重要性,对比了Cookie、Session和JWT三种会话技术,分析其优缺点,并讲解了过滤器与拦截器的统一拦截方案,推荐使用JWT... 目录引言一、登录校验的基本概念二、HTTP协议的无状态性三、会话跟android踪技术1. Cook

springboot项目中集成shiro+jwt完整实例代码

《springboot项目中集成shiro+jwt完整实例代码》本文详细介绍如何在项目中集成Shiro和JWT,实现用户登录校验、token携带及接口权限管理,涉及自定义Realm、ModularRe... 目录简介目的需要的jar集成过程1.配置shiro2.创建自定义Realm2.1 LoginReal