通过Nodejs搭建网站简单实现注册登录流程


Posted in NodeJs onJune 14, 2019

1. 使用Backbone实现前端hash路由

初步设想将注册和登录作为两个不同的url实现,但登录和注册功能的差距只有form表单部分,用两个url实现显然开销过大,所以最终方案为使用hash作为前端路由,根据url的hash值切换相应的表单显示。

很多致力于SPA开发的前端框架都具备hash路由功能,考虑到嗨猫本身是一个类博客、偏重静态展示的网站,所以最后选择了轻量级的Backbone最为前端框架。

Backbone实现hash路由的代码很简单:

let $formBox = $('.box_form_container'),
$navitems = $('.box_nav_item'),
$nav_item_signup = $('.box_nav_item_signup'),
$nav_item_login = $('.box_nav_item_login');
let pwdRouter = Backbone.Router.extend({
routes: {
'login': 'login',
'signup': 'signup'
},
login: function() {
$formBox.removeClass('box_form_container_signup').addClass(
'box_form_container_login');
$navitems.removeClass('box_nav_item-current');
$nav_item_login.addClass('box_nav_item-current');
},
signup: function() {
$formBox.removeClass('box_form_container_login').addClass(
'box_form_container_signup');
$navitems.removeClass('box_nav_item-current');
$nav_item_signup.addClass('box_nav_item-current');
}
});
let router = new pwdRouter();
Backbone.history.start();

务必不要遗漏Backbone.history.start();,否则路由功能不会启动。

随后,将登录和注册的a标签的href分别修改为#login和#signup便实现了简单的hash路由。

2. 使用jquery-validation完善前端表单验证

前端表单验证是必不可少的一项功能,前端的js代码验证表单的完整性并拦截一部分非法的表单输入,一定程度上减少服务端的压力。

初步想自己造轮子,但考虑到开发周期和轮子的成熟性,最终选择jquery-validation插件作为前端表单验证工具。

jquery-validation插件和表单元素的name属性绑定,以登录表单为例,其dom结构如下:

根据input控件的name属性,jquery-validation的验证代码如下:

// 登录表单添加验证规则
$('.login_form').validate({
rules: {
signname: {
required: true,
signname: true
},
password: {
required: true,
norepeat: true
},
verifycode: {
required: true
}
},
errorPlacement: function(error, element) {
let container = element.parent().find('.form_error');
error.appendTo(container);
container.show();
},
submitHandler: function(form) {
var $form = $(form);
let _action = $form.attr('action');
$form.attr('action', '');
$.ajax({
type: 'post',
url: _action,
data: $form.serialize(),
dataType: 'json'
}).done(function(res) {
console.log('done');
if (res.code !== '100') {
alert(res.msg);
} else {
alert('注册成功');
}
}).fail(function(res) {
console.log('fail');
}).always(function() {
$form.attr('action', _action);
});
}
});

其中signname和norepeat是自定义的验证规则,signname如下:

// 添加用户名+邮箱的双重验证规则
$.validator.addMethod('signname', function(value, element) {
let reg_isemail = /[@]/,
reg_email =
/^[a-z]([a-z0-9]*[-_]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\.][a-z]{2,3}([\.][a-z]{2})?$/i;
return !reg_isemail.test(value) || (reg_isemail.test(value) &&
reg_email.test(value));
}, '请输入正确的用户名或邮箱');

用户可以使用用户名或邮箱登录,两者共享一个input控件,signname验证是用户名还是邮箱,如果是邮箱,便保证输入邮箱格式的正确性。

norepeat验证密码不能出现连续3次的字符

  • errorPlacement指明错误提示信息的位置,我们给它提供了一个容器。
  • submitHandler监听submit按钮,首先拦截默认的表单提交请求,替换为自定义的提交逻辑,本项目中使用ajax提交。

并且为了防止用户频繁点击submit按钮造成重复提交,我们首先将form的action属性清空,待请求完毕后重新赋值。

3. 使用node-canvas模块增加验证码功能

node-canvas是一个将canvas API迁移到nodejs使用的扩展模块,使用node-canvas模块可以在nodejs服务器生成图片(当然它的作用不仅限于此,但项目暂时只用到生成图片功能),下面详细讲述如何搭建登录&注册表单验证码功能。

3.1 部署node-canvas依赖环境

node-canvas需要操作系统安装底层图形库,各操作系统的依赖如下:

11111111111

目前开发环境为mac,简单记录一下环境部署操作以及遇到的一些坑。

首先按照上图安装底层库,由于brew安装的Cairo版本过低,将会导致canvas不正确的绘图(参考https://github.com/Automattic/node-canvas/issues/639)。这是Cairo的bug,所以必须保证Cairo版本在1.14.1以上。使用brew更新Cairo:

brew update
brew upgrade Cairo

安装成功后,在项目根目录下安装node-canvas:npm install canvas --save-dev 

至此,环境部署完毕,进入开发阶段。

3.2 服务端

打开api/controllers/Auth/AuthController,添加生成验证码图片的函数generateVerifyImg():

generateVerifyImg: function() {
var _verify = {
code: '',
img: ''
};
// 生成四位数字和字母的数字作为验证码
_verify.code = Math.random().toString(16).slice(2, 6);
var Image = Canvas.Image,
canvas = new Canvas(60, 30),
ctx = canvas.getContext('2d');
var _rotate = (Math.random()).toFixed(2);
ctx.fillStyle = '#ffcc99';
ctx.fillRect(0, 0, 60, 30);
ctx.rotate(_rotate);
ctx.font = 'italic 20px serif';
ctx.strokeStyle = '#424952';
// 将验证码绘制进canvas
ctx.strokeText(_verify.code, 10, 20);
// 生成验证码图片
_verify.img = canvas.toDataURL('image/png');
return _verify;
}

然后在登录&注册的API中生成验证码图片并渲染进模板文件:

/**
* @desc 登录、注册的统一入口,由前端Backbone的hash路由判断展示表单
* @param req
* @param res
*/
toAuth: function(req, res) {
var _verify = this.generateVerifyImg();
req.session.verifycode = _verify.code;
var view = swig.renderFile('./views/passport/main.swig', {
verify_img: _verify.img
});
return res.send(view);
}

其中非常关键的一步是将验证码通过session保存,以便进行验证。

随后,在接受表单post的API中加入验证码过滤逻辑:

if (!req.param('verifycode') || req.param('verifycode') !== req.session
.verifycode) {
return res.json({
err: rescode.invalidVerifycode,
msg: "验证码不正确"
});
}

项目至此已经具备了基本的验证码功能。验证码的一个重要需求是用户手动刷新验证码,下面简单讲述实现过程。

3.3 实现验证刷新功能

1.首先在前端js代码中添加验证码图片刷新事件监听:

$('.hc_container').on('click', '.form_img_verifycode', function() {
console.log('换一换');
var $img = $(this);
$.ajax({
url: '/getverifycode',
type: 'get',
dataType: 'json'
}).done(function(res) {
console.log('getverifycode success');
$img.attr('src', res.img);
}).fail(function(res) {
console.log('getverifycode failed');
});
});

2.然后配置sails的config/route.js:

// 刷新验证码
'get /getverifycode': 'Auth/AuthController.getVerifyImg'

3.在Auth/AuthController中添加getVerifyImg()API接受前端的验证码刷新请求:

getVerifyImg: function(req, res) {
var _verify = this.generateVerifyImg();
req.session.verifycode = _verify.code;
return res.json({
'img': _verify.img
});
}

这个API功能非常简单,获取新的验证码图片并返回给前端,但是必须谨记将验证码通过session记录。

前端通过ajax获取到新的验证码图片url替换旧图即可。

4. 实现登录&注册成功后的页面跳转
由前端js控制跳转,目前统一跳转到首页:

window.location.href='/';

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
14款NodeJS Web框架推荐
Jul 11 NodeJs
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
Dec 18 NodeJs
nodejs批量修改文件编码格式
Jan 22 NodeJs
Nodejs关于gzip/deflate压缩详解
Mar 04 NodeJs
nodejs微信公众号支付开发
Sep 19 NodeJs
简单实现nodejs上传功能
Jan 14 NodeJs
详解nodejs爬虫程序解决gbk等中文编码问题
Apr 06 NodeJs
Nodejs读取文件时相对路径的正确写法(使用fs模块)
Apr 27 NodeJs
nodejs中实现用户注册路由功能
May 20 NodeJs
nodejs实现获取本地文件夹下图片信息功能示例
Jun 22 NodeJs
nodejs对项目下所有空文件夹创建gitkeep的方法
Aug 02 NodeJs
Nodejs监听日志文件的变化的过程解析
Aug 04 NodeJs
NodeJs生成sitemap站点地图的方法示例
Jun 11 #NodeJs
nodejs提示:cross-device link not permitted, rename错误的解决方法
Jun 10 #NodeJs
Nodejs异步流程框架async的方法
Jun 07 #NodeJs
nodejs log4js 使用详解
May 31 #NodeJs
如何让Nodejs支持H5 History模式(connect-history-api-fallback源码分析)
May 30 #NodeJs
nodejs中实现修改用户路由功能
May 24 #NodeJs
nodejs实现用户登录路由功能
May 22 #NodeJs
You might like
用缓存实现静态页面的测试
2006/12/06 PHP
一个数据采集类
2007/02/14 PHP
实例讲解php实现多线程
2019/01/27 PHP
laravel按天、按小时,查询数据的实例
2019/10/09 PHP
Javascript-Mozilla和IE中的一个函数直接量的问题分析
2007/08/12 Javascript
JQuery自定义事件的应用 JQuery最佳实践
2010/08/01 Javascript
Java 正则表达式学习总结和一些小例子
2012/09/13 Javascript
同域jQuery(跨)iframe操作DOM(实例讲解)
2013/12/19 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
2014/01/10 Javascript
在JavaScript中处理时间之getHours()方法的使用
2015/06/10 Javascript
jquery实现鼠标滑过后动态图片提示效果实例
2015/08/10 Javascript
js实现左侧网页tab滑动门效果代码
2015/09/06 Javascript
JavaScript操作XML/HTML比较常用的对象属性集锦
2015/10/30 Javascript
JS实现添加,替换,删除节点元素的方法
2016/06/30 Javascript
AngularJS 中文API参考手册
2016/07/28 Javascript
js如何获取网页所有图片
2017/05/12 Javascript
利用JS制作万年历的方法
2017/08/16 Javascript
JS计算距当前时间的时间差实例
2017/12/29 Javascript
对vue下点击事件传参和不传参的区别详解
2018/09/15 Javascript
Node.js如何对SQLite的async/await封装详解
2019/02/14 Javascript
解决layui的radio属性或别的属性没显示出来的问题
2019/09/26 Javascript
JS Array.from()将伪数组转换成数组的方法示例
2020/03/23 Javascript
详解JavaScript 事件流
2020/09/02 Javascript
Python version 2.7 required, which was not found in the registry
2014/08/26 Python
python开发之基于thread线程搜索本地文件的方法
2015/11/11 Python
tensorflow学习笔记之简单的神经网络训练和测试
2018/04/15 Python
python飞机大战 pygame游戏创建快速入门详解
2019/12/17 Python
python使用正则来处理各种匹配问题
2019/12/22 Python
解决pycharm中的run和debug失效无法点击运行
2020/06/09 Python
YBF Beauty官网:美丽挚友,美国知名彩妆品牌
2020/11/22 全球购物
十岁生日同学答谢词
2014/01/19 职场文书
咖啡蛋糕店创业计划书
2014/01/28 职场文书
期中考试复习计划
2015/01/19 职场文书
反腐倡廉影片观后感
2015/06/08 职场文书
个人催款函范文
2015/06/24 职场文书
SpringBoot 集成Redis 过程
2021/06/02 Redis