使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)


Posted in Javascript onJuly 10, 2011

需要引入插件jquery.md5.js
可直接在IIS下运行;
用户名:Ethan.zhu
密 码:123456789
完整文件下载:WebApplication1_3water.rar

首先将按钮单击事件的异步验证提取出来作为一个单独的函数,需要将按钮单击事件里面的变量提取出来定义为全局变量,并且增加一个变量editPass(用来标记是自己输入密码,还是从cookies中读取的密码)

var wrongTypeName, //用户名的错误类型,可以直接作为错误提示信息数组的下标 
wrongTypePwd, //用户密码的错误类型 
wrongNameHtml = new Array("", "请输入用户名", "用户名长度太短", "用户名长度超过12位", "您的用户名或密码错误", "超时,请重新登陆"), 
wrongPwdHtml = new Array("", "请输入密码", "密码长度小于6位", "", "密码中含有非法字符"), 
editPass=false;

这里从上一篇的按钮单击事件开始:
$(".btn-submit").click(function () { 
wrongTypeName = 0; 
wrongTypePwd = 0; 
var uname = $("#uname").val(), //用户名 
pwd = $("#passwd").val(), //用户密码 
plength = pwd.length, 
nlength = uname.length; //长度 
if (nlength == 0) 
wrongTypeName = 1; 
if (nlength > 0 && nlength < 2) 
wrongTypeName = 2; 
if (nlength > 20) 
wrongTypeName = 3; 
if (plength == 0) 
wrongTypePwd = 1; //这里是对用户名和密码长度的一个判断,并获取错误信息数组的下标。 
else { 
var patrn = /^(\w){6,20}$/; 
if (plength < 6) 
wrongTypePwd = 2; 
if (plength > 50) 
wrongTypePwd = 3; 
if (plength > 6 && plength < 20) { 
if (!patrn.exec(pwd)) 
wrongTypePwd = 4; //这里是对用户密码合法性的前端判断,并返回错误数组的下标 
} 
} inputTip(0, wrongNameHtml, wrongTypeName); 
inputTip(1, wrongPwdHtml, wrongTypePwd); 
if (wrongTypePwd == 0 && wrongTypeName == 0) {//在用户输入信息完全合法的情况下,即数组下标全部为0 开始执行ajax验证 
//alert($.cookie("logout")); 
if(editPass){ 
pwd = $.md5(pwd); 
} 
$("#passwd").val(pwd); 
$("#login-form input").attr('disabled', true); 
$('.remember').unbind('click'); 
//已经向服务器提交了信息,所以将页面上的所有输入框按钮设置成不可用状态,这样可以有效的避免重复提交 
var remb = $('#remember-long').val(); 
ajaxCheck(uname, pwd, remb); 
} 
});

变化在33行和41行,

行用来判断密码是用户在程序内部退出到登录页面的时候是自行输入还是从cookies中读取的。防止二次加密造成服务器验证失败。

行主要是将ajax处理过程提取出来,同时加入了服务器验证成功之后的记住密码和取消记住密码的操作,方便阅读:

var ajaxCheck = function (uname, pwd, remb) { 
$(".btn-master").addClass("visibility"); 
var $params = "user_name=" + decodeURI(uname) + "&user_pwd=" + decodeURI(pwd) + "&remember=" + decodeURI(remb); 
$.ajax({ 
type: 'POST', 
url: 'CheckUserLogin.aspx', 
//async: false, 
cache: false, 
dataType: 'json' 
data: $params, 
success: function (data, status) { 
wrongTypeName = data.wrongTypeName; 
wrongTypePwd = data.wrongTypePwd; 
var loginSuccess = data.loginSuccess; //获取服务器返回的json数据 
if (loginSuccess == 0) { 
if ($('#remember-long').val() == 1) {//记住密码 
$.cookie('UserName', uname, { expires: 7, path: '/' }); 
$.cookie('Password', pwd, { expires: 7, path: '/' }); 
} 
else if ($('#remember-long').val() == 0) {//取消记住的密码,或者没有记住密码 
$.cookie('UserName', null,{ expires: 7, path: '/' }); 
$.cookie('Password', null,{ expires: 7, path: '/' }); 
} 
location.href = "/Members/Members.html" 
} 
else { 
$(".btn-master").removeClass("visibility"); 
$("#login-form input").attr('disabled', false); 
inputTip(0, wrongNameHtml, wrongTypeName); 
inputTip(1, wrongPwdHtml, wrongTypePwd); 
} 
}, 
error: function () { 
wrongTypeName = 5; 
inputTip(0, wrongNameHtml, wrongTypeName); 
$("#login-form input").attr('disabled', false); 
$('.remember').bind('click', function () { checkClick(); }); 
$(".btn-master").removeClass("visibility"); 
} 
}) 
}

页面初始化的时候要对记住密码这个过程进行处理:
var rememberPassword = function (logout) {//页面加载完成之后执行自动登录检查 
var ckname = $.cookie('UserName'); 
var ckpwd = $.cookie("Password"); 
if (ckname != "" && ckpwd != "" && ckname != null && ckpwd != null) { 
$('#remember-long').val("1") 
$('#remember-long').attr('checked', true); 
$("#uname").val(ckname); //用户名 
$('.reg-item').addClass('focus'); 
if (logout=="safe"){ 
$.cookie("logout","",{ expires: 1, path: '/' }) 
} 
else{ 
$("#passwd").val(ckpwd); //用户密码 
$(".btn-submit").trigger('click'); //自动登录 
} 
} 
else { 
$('#remember-long').val("0") 
$('#remember-long').attr('checked', false); 
} 
} var logout = $.cookie("logout"); 


//判断用户是否是从内部退出还是直接打开 
//如果是从内部退出,那么就不能再次自动登录进去,除非用户刷新了页面 
rememberPassword(logout);

下面是完整的全新的前端脚本:
$(function () { var wrongTypeName, //用户名的错误类型,可以直接作为错误提示信息数组的下标 
wrongTypePwd, //用户密码的错误类型 
wrongNameHtml = new Array("", "请输入用户名", "用户名长度太短", "用户名长度超过12位", "您的用户名或密码错误", "超时,请重新登陆"), 
wrongPwdHtml = new Array("", "请输入密码", "密码长度小于6位", "", "密码中含有非法字符"), 
editPass=false; 
$('body').focus(); //让输入框不再自动获取焦点 
$('.reg-action .reg-input').each(function () { 
var items = $(this).parent('.reg-item'); 
if ($(this).val()) { 
items.addClass("focus"); 
} 
$(this).bind('focus blur', function (event) { 
var type = event.type; //获取事件类型 
if($(this).attr("id")=="passwd"){ 
editPass = true; 
} 
if (type == 'focus') { 
if (items.hasClass('error')) { 
$(this).val(""); 
items.removeClass('error'); 
} 
items.addClass('focus'); 
} else if (!$(this).val()) { 
items.removeClass('focus'); 
} 
}) 
}); 
$(".btn-submit").click(function () { 
wrongTypeName = 0; 
wrongTypePwd = 0; 
var uname = $("#uname").val(), //用户名 
pwd = $("#passwd").val(), //用户密码 
plength = pwd.length, 
nlength = uname.length; //长度 
if (nlength == 0) 
wrongTypeName = 1; 
if (nlength > 0 && nlength < 2) 
wrongTypeName = 2; 
if (nlength > 20) 
wrongTypeName = 3; 
if (plength == 0) 
wrongTypePwd = 1; //这里是对用户名和密码长度的一个判断,并获取错误信息数组的下标。 
else { 
var patrn = /^(\w){6,20}$/; 
if (plength < 6) 
wrongTypePwd = 2; 
if (plength > 50) 
wrongTypePwd = 3; 
if (plength > 6 && plength < 20) { 
if (!patrn.exec(pwd)) 
wrongTypePwd = 4; //这里是对用户密码合法性的前端判断,并返回错误数组的下标 
} 
} 
inputTip(0, wrongNameHtml, wrongTypeName); 
inputTip(1, wrongPwdHtml, wrongTypePwd); 
if (wrongTypePwd == 0 && wrongTypeName == 0) {//在用户输入信息完全合法的情况下,即数组下标全部为0 开始执行ajax验证 
//alert($.cookie("logout")); 
if(editPass){ 
pwd = $.md5(pwd); 
} 
$("#passwd").val(pwd); 
$("#login-form input").attr('disabled', true); 
$('.remember').unbind('click'); 
//已经向服务器提交了信息,所以将页面上的所有输入框按钮设置成不可用状态,这样可以有效的避免重复提交 
var remb = $('#remember-long').val(); 
ajaxCheck(uname, pwd, remb); 
} 
}); 
var inputTip = function (index, tipHtml, tipNum) { 
$(".reg-tip").eq(index).html(tipHtml[tipNum]); 
if (tipNum > 0) 
$(".reg-item").eq(index).addClass("error"); 
else 
$(".reg-item").eq(index).removeClass("error"); 
} //定义错误提示信息页面显示函数。由于页面只有两个输入框所以我这里直接指定了index,如果页面上有很多,可以使用$(this).index() 
var ajaxCheck = function (uname, pwd, remb) { 
$(".btn-master").addClass("visibility"); 
var $params = "user_name=" + decodeURI(uname) + "&user_pwd=" + decodeURI(pwd) + "&remember=" + decodeURI(remb); 
$.ajax({ 
type: 'POST', 
url: 'CheckUserLogin.aspx', 
//async: false, 
cache: false, 
dataType: 'json', 
data: $params, 
success: function (data, status) { 
wrongTypeName = data.wrongTypeName; 
wrongTypePwd = data.wrongTypePwd; 
var loginSuccess = data.loginSuccess; //获取服务器返回的json数据 
if (loginSuccess == 0) { 
if ($('#remember-long').val() == 1) {//记住密码 
$.cookie('UserName', uname, { expires: 7, path: '/' }); 
$.cookie('Password', pwd, { expires: 7, path: '/' }); 
} 
else if ($('#remember-long').val() == 0) {//取消记住的密码,或者没有记住密码 
$.cookie('UserName', null,{ expires: 7, path: '/' }); 
$.cookie('Password', null,{ expires: 7, path: '/' }); 
} 
location.href = "/Members/Members.html" 
} 
else { 
$(".btn-master").removeClass("visibility"); 
$("#login-form input").attr('disabled', false); 
inputTip(0, wrongNameHtml, wrongTypeName); 
inputTip(1, wrongPwdHtml, wrongTypePwd); 
} 
}, 
error: function () { 
wrongTypeName = 5; 
inputTip(0, wrongNameHtml, wrongTypeName); 
$("#login-form input").attr('disabled', false); 
$('.remember').bind('click', function () { checkClick(); }); 
$(".btn-master").removeClass("visibility"); 
} 
}) 
} 
var checkClick = function () { 
if ($('#remember-long').attr('checked')) { 
$('#remember-long').attr('checked', false); 
$('#remember-long').val("0") 
} 
else { 
$('#remember-long').attr('checked', true); 
$('#remember-long').val("1") 
} 
} 
$('.remember').bind('click', function () { checkClick(); }); 
$("#remember-long").click(function () { checkClick(); }); 
//记住登录的checkbox和label点击的绑定。 
if ($.browser.msie && $.browser.version == "6.0") { 
//帮助微软消灭ie6 
if ($.cookie('masterShow') != "hidden") 
$('body').append('<div class="master"><p>您的浏览器是<strong>IE6.0</strong>,漏洞较多,用户体验较差,微软官方将要放弃支持,为了自身电脑安全和获取最佳用户体验建议你根据自身需求升级至<a href="http://windows.microsoft.com/zh-CN/internet-explorer/downloads/ie-8" target="_blank" class="red"><strong>IE8.0</strong></a>以上版本或者使用<a href="http://firefox.com.cn/" target="_blank" class="red"><strong>火狐</strong></a>浏览器</p></div><div class="m-close m-close-short">关闭</div><div class="m-close m-close-long">不再显示</div>'); 
$(".master").delay(1000).slideDown('', function () { 
$(".m-close").fadeIn(); 
}); 
$(".m-close-short").click(function () { 
$(".m-close").fadeOut('', function () { 
$(".master").slideUp(); 
}); 
}); 
$(".m-close-long").click(function () { 
$(".m-close").fadeOut('', function () { 
$(".master").slideUp(); 
$.cookie('masterShow', 'hidden'); 
}); 
}); 
} 
var rememberPassword = function (logout) {//页面加载完成之后执行自动登录检查 
var ckname = $.cookie('UserName'); 
var ckpwd = $.cookie("Password"); 
if (ckname != "" && ckpwd != "" && ckname != null && ckpwd != null) { 
$('#remember-long').val("1") 
$('#remember-long').attr('checked', true); 
$("#uname").val(ckname); //用户名 
$('.reg-item').addClass('focus'); 
if (logout=="safe"){ 
$.cookie("logout","",{ expires: 1, path: '/' }) 
} 
else{ 
$("#passwd").val(ckpwd); //用户密码 
$(".btn-submit").trigger('click'); //自动登录 
} 
} 
else { 
$('#remember-long').val("0") 
$('#remember-long').attr('checked', false); 
} 
} 
var logout = $.cookie("logout");//判断用户是否是从内部退出 
rememberPassword(logout); 
$(document).bind('keydown', 'return', function () { $(".btn-submit").trigger('click'); }); 
})

关于页面中涉及的后台程序,我用了页面级别的aspx,当然你也可以使用ashx来处理。这个后台处理负责验证密码是否正确并在用户正确登录的情况下设置session值,如果需要演示,可以在后台定义常量来做验证判断:
Hashtable ht = new Hashtable(); 
string uname = Request.Params["user_name"]; 
string pwd = Request.Params["user_pwd"]; 
int wrongTypeName = 0; 
int wrongTypePwd = 0; 
uname = PageValidate.InputText(uname, 30); if (Validator.StrIsNullOrEmpty(uname)) 
{ 
wrongTypeName = 1; 
} 
if (Validator.StrIsNullOrEmpty(pwd)) 
{ 
wrongTypePwd = 1; 
} 
if (!string.IsNullOrEmpty(uname) && !string.IsNullOrEmpty(pwd)) 
{ 
//以下使用常量来做演示: 
string userName="ethan.zhu"; 
string password ="";//需要MD5加密之后的字符串 
if (uname==userName&&password==pwd ) 
ht.Add("loginSuccess", 0); 
else 
wrongTypeName = 4;//返回用户名或密码错误 
if (wrongTypeName > 0 || wrongTypePwd > 0) 
{ 
ht.Add("wrongTypeName", wrongTypeName); 
ht.Add("wrongTypePwd", wrongTypePwd); 
} 
Response.Write(CreateJsonParams(ht)); 
} 
Response.End(); 
}

将Hashtable转换成json:
public static string CreateJsonParams(Hashtable items) 
{ 
string returnStr = ""; 
foreach (DictionaryEntry item in items) 
{ 
returnStr += "\"" + item.Key.ToString() + "\":\"" + item.Value.ToString() + "\","; 
} 
return "{" + returnStr.Substring(0, returnStr.Length - 1) + "}"; }
Javascript 相关文章推荐
JQuery 表格操作(交替显示、拖动表格行、选择行等)
Jul 29 Javascript
Javascript 刷新全集常用代码
Nov 22 Javascript
麻雀虽小五脏俱全 Dojo自定义控件应用
Sep 04 Javascript
js分页工具实例
Jan 28 Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
Oct 26 Javascript
JS表格组件神器bootstrap table使用指南详解
Apr 12 Javascript
基于jQuery的表单填充实例
Aug 22 jQuery
jQuery实现表单动态加减、ajax表单提交功能
Jun 08 jQuery
js中事件对象和事件委托的介绍
Jan 21 Javascript
node.js中事件触发器events的使用方法实例分析
Nov 23 Javascript
es6函数之尾调用优化实例分析
Apr 25 Javascript
使用vue编写h5公众号跳转小程序的实现代码
Nov 27 Vue.js
JQuery 自定义CircleAnimation,Animate方法学习笔记
Jul 10 #Javascript
关于jQuery中的end()使用方法
Jul 10 #Javascript
动感效果的TAB选项卡jquery 插件
Jul 09 #Javascript
使用Jquery打造最佳用户体验的登录页面的实现代码
Jul 08 #Javascript
33个优秀的jQuery 教程分享(幻灯片、动画菜单)
Jul 08 #Javascript
jquery 选项卡效果 新手代码
Jul 08 #Javascript
基于jquery实现图片广告轮换效果代码
Jul 07 #Javascript
You might like
php与php MySQL 之间的关系
2009/07/17 PHP
apache和php之间协同工作的配置经验分享
2013/04/08 PHP
thinkphp中连接oracle时封装方法无法用的解决办法
2013/06/17 PHP
css图片自适应大小
2007/11/28 Javascript
Javascript 更新 JavaScript 数组的 uniq 方法
2008/01/23 Javascript
解析JSON对象与字符串之间的相互转换
2013/12/18 Javascript
无限树Jquery插件zTree的常用功能特性总结
2014/09/11 Javascript
AngularJS Module方法详解
2015/12/08 Javascript
JavaScript几种数组去掉重复值的方法推荐
2016/04/12 Javascript
Node.js  事件循环详解及实例
2017/08/06 Javascript
jQuery实现动态添加节点与遍历节点功能示例
2017/11/09 jQuery
在layer弹层layer.prompt中,修改placeholder的实现方法
2019/09/27 Javascript
微信小程序实现搜索功能
2020/03/10 Javascript
python中ConfigParse模块的用法
2014/09/29 Python
Python实现的多线程端口扫描工具分享
2015/01/21 Python
Python检测生僻字的实现方法
2016/10/23 Python
Python时间获取及转换知识汇总
2017/01/11 Python
python实现rsa加密实例详解
2017/07/19 Python
python多进程中的内存复制(实例讲解)
2018/01/05 Python
Django中使用Celery的方法示例
2018/11/29 Python
python3.6使用tkinter实现弹跳小球游戏
2019/05/09 Python
python队列原理及实现方法示例
2019/11/27 Python
python切割图片的示例
2020/11/12 Python
美国知名女性服饰品牌:New York & Company
2017/03/23 全球购物
NULL是什么,它是怎么定义的
2015/05/09 面试题
生产班组长岗位职责
2014/01/05 职场文书
打架检讨书100字
2014/01/19 职场文书
《雷鸣电闪波尔卡》教学反思
2014/02/23 职场文书
群众路线剖析材料怎么写
2014/10/09 职场文书
英文商务邀请函范文
2015/01/31 职场文书
如何用JavaScript学习算法复杂度
2021/04/30 Javascript
浅谈mysql返回Boolean类型的几种情况
2021/06/04 MySQL
Java实现多线程聊天室
2021/06/26 Java/Android
「地球外少年少女」BD发售宣传CM公开
2022/03/21 日漫
Win11跳过联网界面创建本地管理账户的3种方法
2022/04/20 数码科技
搭建zabbix监控以及邮件报警的超级详细教学
2022/07/15 Servers