通过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 相关文章推荐
用nodejs写的一个简单项目打包工具
May 11 NodeJs
Nodejs极简入门教程(三):进程
Oct 27 NodeJs
NodeJS制作爬虫全过程
Dec 22 NodeJs
Windows系统中安装nodejs图文教程
Feb 28 NodeJs
ubuntu下安装nodejs以及升级的办法
May 08 NodeJs
Nodejs全局安装和本地安装的不同之处
Jul 04 NodeJs
NodeJS远程代码执行
Aug 28 NodeJs
Nodejs高扩展性的模板引擎 functmpl简介
Feb 13 NodeJs
基于Nodejs利用socket.io实现多人聊天室
Feb 22 NodeJs
详解nodejs微信公众号开发——2.自动回复
Apr 10 NodeJs
详解nodejs模板引擎制作
Jun 14 NodeJs
nodejs 如何手动实现服务器
Aug 20 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
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
PHP查询快递信息的方法
2015/03/07 PHP
分析PHP中单双引号的误区和双引号小隐患
2016/07/19 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
JavaScript网页制作特殊效果用随机数
2007/05/22 Javascript
jQuery入门知识简介
2010/03/04 Javascript
range 标准化之获取
2011/08/28 Javascript
dotopAlert 提示用户需安装播放器的代码
2012/09/17 Javascript
javascript打印大全(打印页面设置/打印预览代码)
2013/03/29 Javascript
JavaScript的原型继承详解
2015/02/15 Javascript
微信小程序 wx.request(object) API详解及实例代码
2016/09/30 Javascript
jQuery用noConflict代替$的实现方法
2017/04/12 jQuery
从零开始学习Node.js系列教程四:多页面实现的数学运算示例
2017/04/13 Javascript
js实现扫雷小程序的示例代码
2017/09/27 Javascript
Vue-router 切换组件页面时进入进出动画方法
2018/09/01 Javascript
微信小程序防止多次点击跳转和防止表单组件输入内容多次验证功能(函数防抖)
2019/09/19 Javascript
vue props default Array或是Object的正确写法说明
2020/07/30 Javascript
浅谈vue 二级路由嵌套和二级路由高亮问题
2020/08/06 Javascript
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
python中的全局变量用法分析
2015/06/09 Python
python处理按钮消息的实例详解
2017/07/11 Python
python3结合openpyxl库实现excel操作的实例代码
2018/09/11 Python
一文解决django 2.2与mysql兼容性问题
2020/07/15 Python
THE OUTNET英国官网:国际设计师品牌折扣网站
2016/08/14 全球购物
购买中国最好的电子产品:Geekbuying
2018/03/13 全球购物
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
俄罗斯金苹果网上化妆品和香水商店:Goldapple
2019/12/01 全球购物
高中微机老师自我鉴定
2014/02/16 职场文书
退休教师欢送会主持词
2014/03/31 职场文书
法人代表任命书范本
2014/06/05 职场文书
晚自修旷课检讨书怎么写
2014/11/17 职场文书
2015年教师节活动总结
2015/03/20 职场文书
欠款起诉书范文
2015/05/19 职场文书
爱国主义电影观后感
2015/06/18 职场文书
开学随笔
2015/08/15 职场文书
2016年村党支部公开承诺书
2016/03/24 职场文书