使用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 相关文章推荐
javascript中字符串拼接需注意的问题
Jul 13 Javascript
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
Apr 01 Javascript
javascript中parseInt()函数的定义和用法分析
Dec 20 Javascript
深入浅析JS的数组遍历方法(推荐)
Jun 15 Javascript
javascript实现的全国省市县无刷新多级关联菜单效果代码
Aug 01 Javascript
JavaScript实现复制文章自动添加版权
Aug 02 Javascript
浅谈bootstrap使用中的一些问题以及解决过程
Oct 18 Javascript
vue父组件点击触发子组件事件的实例讲解
Feb 08 Javascript
Vue.js 表单控件操作小结
Mar 29 Javascript
JS实现求5的阶乘示例
Jan 21 Javascript
vue+element表格导出为Excel文件
Sep 26 Javascript
JS相册图片抖动放大展示效果的示例代码
Jan 29 Javascript
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一些公用函数的集合
2008/03/27 PHP
优化php效率,提高php性能的一些方法
2011/03/24 PHP
解析PHP中ob_start()函数的用法
2013/06/24 PHP
PHP判断一个数组是另一个数组子集的方法详解
2017/07/31 PHP
Gird事件机制初级读本
2007/03/10 Javascript
基于jquery的网页SELECT下拉框美化代码
2010/10/28 Javascript
jquery 全局AJAX事件使用代码
2010/11/05 Javascript
jquery.cookie用法详细解析
2013/12/18 Javascript
js动态添加onclick事件可传参数与不传参数
2014/07/29 Javascript
基于jquery实现等比缩放图片
2014/12/03 Javascript
js 求时间差的实现代码
2016/04/26 Javascript
浅析Bootstrap表格的使用
2016/06/23 Javascript
前端js实现文件的断点续传 后端PHP文件接收
2016/10/14 Javascript
Vue-Cli中自定义过滤器的实现代码
2017/08/12 Javascript
vee-validate vue 2.0自定义表单验证的实例
2018/08/28 Javascript
发布Angular应用至生产环境的方法
2018/12/10 Javascript
vue前端框架—Mint UI详解(更适用于移动端)
2019/04/30 Javascript
vue使用nprogress加载路由进度条的方法
2020/06/04 Javascript
vue cli 3.0通用打包配置代码,不分一二级目录
2020/09/02 Javascript
[02:33]DOTA2英雄基础教程 司夜刺客
2013/12/04 DOTA
[12:29]2018国际邀请赛 开幕秀
2018/08/22 DOTA
[03:40]DOTA2抗疫特别篇《英雄年代》
2020/02/28 DOTA
Python开发之快速搭建自动回复微信公众号功能
2016/04/22 Python
python使用super()出现错误解决办法
2017/08/14 Python
Django Admin后台模型列表页面如何添加自定义操作按钮
2020/11/11 Python
全球度假村:Club Med
2017/11/27 全球购物
英国比较机场停车场网站:Airport Parking Essentials
2019/12/01 全球购物
企业出纳岗位职责
2014/03/12 职场文书
好的促销活动方案
2014/08/21 职场文书
忠诚奉献演讲稿
2014/09/12 职场文书
医生个人自我剖析材料
2014/10/08 职场文书
少先队辅导员事迹材料
2014/12/24 职场文书
怎样写家长意见
2015/06/04 职场文书
《分数乘法》教学反思
2016/02/24 职场文书
《给予树》教学反思
2016/03/03 职场文书
css3 选择器
2022/05/11 HTML / CSS