热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Node.js用户注册功能的实现

文章目录前言一、项目结构二、用户注册功能的实现1.前端-注册入口2.前端-路由中间件测试3.前端-请求发送4.后端-请求接收5.后端-请求处理&数据库操作总结前言最近一直在忙着练


文章目录

  • 前言
  • 一、项目结构
  • 二、用户注册功能的实现
    • 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);})})
}



总结

如果这篇文章对您有帮助,我很高兴。当然,如果您发现了我的错误,可以在评论区写下您的看法。

在这里插入图片描述
《捋一捋思路》

因为快要期末还成绩稀烂不得不复习来避免挂科的屑.

下一篇打算记一下用户列表的翻动请求实现。


推荐阅读
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • 本文介绍了ASP.NET Core MVC的入门及基础使用教程,根据微软的文档学习,建议阅读英文文档以便更好理解,微软的工具化使用方便且开发速度快。通过vs2017新建项目,可以创建一个基础的ASP.NET网站,也可以实现动态网站开发。ASP.NET MVC框架及其工具简化了开发过程,包括建立业务的数据模型和控制器等步骤。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • node.jsurlsearchparamsAPI哎哎哎 ... [详细]
  • javascript  –  RTL布局中的bootstrap datepicker无法正常工作
    RTL布局中的bootstrapdatepicker工作不正常,我正在使用这个bootstrapdatepickerhttp:bootstrap-datepicker.readth ... [详细]
  • vue使用
    关键词: ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • SpringBoot简单日志配置
     在生产环境中,只打印error级别的错误,在测试环境中,可以调成debugapplication.properties文件##默认使用logbacklogging.level.r ... [详细]
author-avatar
ik82jht
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有