Node.js 用户注册功能的实现
文章目录
- 前言
- 一、项目结构
- 二、用户注册功能的实现
- 1.前端-注册入口
- 2.前端-路由中间件测试
- 3.前端-请求发送
- 4.后端-请求接收
- 5.后端-请求处理&数据库操作
- 总结
前言
最近一直在忙着练这个项目, 所以…没有写甚麽东西, 哈哈.
现在这个管理项目已经有了基本的模样, 实现了用户注册功能和用户列表翻动(这个下篇说), 我打算暂时打住先捋一捋思路.
页面基本样貌的实现就先不记录了, 我使用的是bootstrap.
记录一下用户注册功能的实现吧, 列表翻动。。。以后再说 doge)
一、项目结构
数据库: noSQL数据库 MongoDB
前端:
目录 | 方法 |
---|---|
controllers | 存放前端路由中间件(包含各种请求方法); |
routes | 负责完成路由系统, 依据URL改变来变化页面; |
views | 存放页面中各个模块的模板, 和页面的模板; |
app.js | 完成各类插件配置(该部分不是重点); |
后端:
目录名 | 作用 |
---|---|
controllers | 存放抽离出的后端路由中间件, 对前端路由中间件中做出的请求进行回应; |
models | 负责存放一些方法, 会在controllers中调用的那种, 简化中间件代码. |
public | 静态资源目录 |
routes | 负责完成后端路由, 对相应前端路由做出的请求进行回应. |
utils | 负责与数据库链接, 进行数据库操作,包含且不限于用户信息出入库. |
views | 存放一些ejs页面模板, 由controllers中的中间件负责决定渲染. |
二、用户注册功能的实现
1.前端-注册入口
现在点击"添加"按钮可以弹出用户名密码输入框, 需要实现 输入后点击"保存"将该用户添加至用户列表的功能.
现在先来完成前端部分吧, 样式和HTML就不说了, 因为涉及到元素id, 我截个图看下:
这段代码构成了注册用户的下拉表单.
2.前端-路由中间件测试
在这份bootstrap中已经对应好的逻辑是: 点击下拉注册表单中的"保存"按钮, 导致前端路由中间件"signup"触发(对,它不是由路由驱动的), 向后端发送用户注册信息, 然后在后端加密存储.
我们要先保证客户端的URL跳转到"/signup"后能够触发前端路由中间件"signup", 现在先来测试一下:
// frontend/src/controllers/indexconst _signup = () => {console.log("signup");
}
在controllers中完成中间件"signup", 并不需要暴露, 只要在中间件index(这是生成页面必需的中间件)中为其注册点击事件即可:
// frontend/src/controllers/indexconst index = (router) => {return (req, res, next) => {res.render(htmlIndex); //触发Index后渲染主页的模板到页面$(window, '.wrapper').resize(); //在index的中间件中执行resize()优先得到执行;$('#content').html(usersTpl()); //渲染#content元素为usersTpl模块$('#users-save').on('click', _signup); //为"保存"按钮注册点击事件}
}export { signin, index };
signup方法不由路由直接进行触发
$('#users-save').on('click', _signup);
3.前端-请求发送
现在点击已经添加可以触发signup方法了, 在signup中完成请求, 向后端发送用户注册信息即可.
如果在点击保存之后, 注册框停在原地不动,用户会感觉反馈不足, 我们应该让它自己收上去, 表示
“我已经弄完了, 你可以做点别的了.”
这步只需要调用"关闭"按钮的回调函数即可.
// frontend/src/controllers/indexconst _signup = () => {const $btnClose = $('#users-close');const data = $('#users-form').serialize(); //疑问:serialize?$.ajax({ //向接口发送post请求url: '/api/users/signup',type: 'post',data,success(res) {console.log(res);}})$btnClose.click(); //回调关闭按钮的函数
}
就先向这个接口发送请求吧/api/users/signup.
4.后端-请求接收
后端对前端请求的监听是通过后端路由来实现的, 在前端向接口发送请求时, 后端在这个接口URL上注册路由方法, 大致是通过这种方法来进行:
前端监听users的URL, 后端监听frontEnd的URL.
// backend/routes/usersvar express = require('express');
var router = express.Router();
const { signup, list } = require('../controllers/users.js');router.post('/signup', signup); //这里的signup是后端路由中间件//其他路由中间件暂略;
module.exports = router;
这样前端向
/api/users/signup
接口
发送请求就可以触发后端的signup方法.
5.后端-请求处理&数据库操作
到这里前端向接口发送请求, 后端已经能够正确的进行接收, 但是我前端发请求是要请您老去帮我办点事儿, 你这仅仅是接收请求是不行的, 我们要在signup中进行一些操作.
数据库操作我们不在signup中完成, 有关数据库的操作集中封装成方法存放在backend/model/users
中, 在signup中调用这些方法并传参需要入库的数据即可, 本处注册用户只用到了一个findUser():
// backend/model/users 集中封存数据库方法const { Users } = require('../utils/db'); //db.js见下段代码const findUser = (username) => {return Users.findOne({ username }); //model.findOne(), 数据库去重查找//findOne()只能传入对象
}
// backend/utils/db 链接, 操作数据库const mongoose = require('mongoose');mongoose.connect('mongodb://localhost/lagou-admin',{useNewUrlParser: true,useUnifiedTopology: true
});let db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));//构建users的model
let usersSchema = mongoose.Schema({username: String,password:String,
});let Users = mongoose.model('users', usersSchema);exports.Users = Users
好吧, 现在你也知道findUser()在数据库里会干点什么了, 我们来看signup吧.
请求是一个复杂的过程, 数据库的检索需要时间, 用户信息必须要进行加密, 这也需要时间, 但JavaScript是一门单线程的语言, 我们应该用异步来优化这个方案.
用async-await
来完成吧…
要将用户注册信息入库, 必然要先获取到信息的, 传入req, res, next三个参数来完成接收, 发送等操作.
在后端为用户信息加密的主要目的是防止内部人员泄密用户数据, so, 在入库之前就要加密, 在拿到数据之后直接加密, 其他操作都先放一放(向加密方法hash()传参即可返回加密后数据, 有关hash()的详情我放到文末了, 再扯下去这signup就没法说了).
//backend/controllers/usersconst usersModel = require('../models/users');
const { hash } = require('../utils/tools');const signup = async (req, res, next) => {res.set('content-type', 'application/json;charset=utf-8');const { username, password } = req.body//密码传输过程中需要加密;const bcryptPassword = await hash(password); //密码加密使用的是bcrypt,所以取名为...let findResult = await usersModel.findUser(username); //看看数据库里是否已经存在该用户.//findUser, model/users.js中的方法,令数据库去重查找该用户并返回.if (findResult) {//用户名已存在res.render('fail.ejs', { //发送注册失败页面:用户名已存在data: JSON.stringify({message: '用户名已存在',})})} else {//数据库中无该用户, 帮其注册, 这里不异步,不然注册失败后也发个成功的页面过去就不好了.let result = await usersModel.signup({ //向models/users中signup传参用户名密码以入库.username,password: bcryptPassword //将bcrypt加密后的用户信息入库;})res.render('succ.ejs', { //等到注册完成再发送页面: 注册成功data: JSON.stringify({message: '注册成功',})});}
}
好吧, 那我们来看看这个hash()加密, 这是用bcrypt插件实现的:
//backend/utils/toolsconst bcrypt = require('bcrypt');exports.hash = (myPlaintextPassword) => { //接收待加密数据return new Promise((resolve, reject) => { //bcrypt.hash()本不返回Promise对象, 需要自己封装.bcrypt.hash(myPlaintextPassword, 10, function (err, hash) {if (err) {reject(err);}resolve(hash);})})
}
总结
如果这篇文章对您有帮助,我很高兴。当然,如果您发现了我的错误,可以在评论区写下您的看法。
《捋一捋思路》
因为快要期末还成绩稀烂不得不复习来避免挂科的屑.
下一篇打算记一下用户列表的翻动请求实现。
Node.js 用户注册功能的实现相关推荐
- 如何调试Node.js应用程序?
如何调试Node.js服务器应用程序? 现在,我主要使用带有以下打印语句的警报调试 : sys.puts(sys.inspect(someVariable)); 必须有更好的调试方法. 我知道Goog ...
- android studio使用nodejs本地服务器json数据_使用Node.js的Alexa技巧
可以使用AlexaLambda函数或RESTAPI端点开发Alexa技能.Lambda函数是Amazon实现AWS中提供的无服务器功能.Amazon建议使用Lambda函数,尽管它们不容易调试.虽然您 ...
- node JS獲取GPS_Node.js 14 正式发布:V8 引擎升级,新增异步本地存储 API
Node.js 14 版本于近日正式发布, 此版本包含的亮点如下: 对诊断功能的改进 升级 v8 引擎 新增实验性的异步本地存储 API 强化流 API 移除实验性模块中的警告 移除一部分早期版本中废 ...
- 什么是node网站服务器,node.js
Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动.非阻塞式I/O模型,[1] 让JavaScript 运 ...
- js 延迟几秒执行_深入研究 Node.js 的回调队列
队列是 Node.js 中用于有效处理异步操作的一项重要技术. 在本文中,我们将深入研究 Node.js 中的队列:它们是什么,它们如何工作(通过事件循环)以及它们的类型. Node.js 中的队列是 ...
- Node.js 文档(目录)
Node.js 文档 Node.js®是基于Chrome的V8 JavaScript引擎构建的JavaScript运行时. 提供以下几种类型的文档: API参考文档 ES6功能 指南 API参考文档 ...
- Deno入门教程:Node.js 的替代品
转自:微点阅读 https://www.weidianyuedu.com 这几天假期,我学习了一下 Deno[1].它是 Node.js 的替代品.有了它,将来可能就不需要 Node.js 了. 这 ...
- 君の古风操作系统Haiku现已支持Node.js
曾经有一款名为 BeOS 的操作系统,由于该厂家自身原因于 2001 年终止开发并被 Palm 公司所收购,从此更名便有了 Haiku 操作系统,不过 Haiku 操作系统延续了 BeOS 的用户体验 ...
- 【Lovea Chino】Node.js 仙侠传(第一部)
Node.js 仙侠传(第一部) 欢迎来到Node.js打通前后端链接的世界 Node.js 学习清单 基础 Soft 安装准备 傻瓜安装Node.js Wins 安装 Vim 编辑器 为你的Vim ...
最新文章
- 常用start_Excel VBA 基础(02.7) - 常用函数 第二部分
- python提取txt中指定内容_提取视频中的音频——python三行程序搞定!
- 面向对象程序设计第二次作业(2)
- 【渝粤题库】国家开放大学2021春1254计算机组成原理题目
- 线段树hdu1754
- linux修正磁盘错误,找到了linux分区顺序错乱修复方法
- java bfs dfs_java优先搜索(DFS/BFS)实际应用
- Git分布式版本控制
- win98 支持html5,win98 ghost ghost在WIN98怎么使用
- 屏蔽CDSN烦人的广告
- lgv30刷android10,记一次LG V30系列手机完美刷入MIUI12系统和Flyme刷机教程
- 简单的w7-->w10的方法
- Android Studio 问题:improperly specified vm option
- python代码时钟_时钟 - python代码库 - 云代码
- memcpy函数(多积累进大厂)
- 目前有哪些比较好的App流量变现的方法?
- 码农小白 设计模式篇 状态模式
- win32 api CreateWindow创建窗口控件及设置字体
- mysql 距离计算排序
- 计算机基础之透析我家的组装机