使用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 相关文章推荐
JS 控制CSS样式表
Aug 20 Javascript
JavaScript高级程序设计(第3版)学习笔记6 初识js对象
Oct 11 Javascript
js removeChild 方法深入理解
Aug 16 Javascript
简单实现JavaScript图片切换效果
Nov 28 Javascript
Vue实现自带的过滤器实例
Mar 09 Javascript
vue+echarts实现动态绘制图表及异步加载数据的方法
Oct 17 Javascript
vue通过video.js解决m3u8视频播放格式的方法
Jul 30 Javascript
vue实现登录页面的验证码以及验证过程解析(面向新手)
Aug 02 Javascript
javascript事件监听与事件委托实例详解
Aug 16 Javascript
微信小程序实现手势滑动效果
Aug 26 Javascript
JS+Canvas实现五子棋游戏
Aug 26 Javascript
JavaScript中document.activeELement焦点元素介绍
Nov 27 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
神族 PROTOSS 概述
2020/03/14 星际争霸
通用PHP动态生成静态HTML网页的代码
2010/03/04 PHP
elgg 获取文件图标地址的方法
2010/03/20 PHP
如何使用GDB调试PHP程序
2015/12/08 PHP
php设计模式之组合模式实例详解【星际争霸游戏案例】
2020/03/27 PHP
firefox下对ajax的onreadystatechange的支持情况分析
2009/12/14 Javascript
jQuery中的val()示例应用
2014/02/26 Javascript
基于JavaScript实现熔岩灯效果导航菜单
2017/01/04 Javascript
Angular2库初探
2017/03/01 Javascript
详解ES6中的三种异步解决方案
2018/06/28 Javascript
Vue表单及表单绑定方法
2018/09/04 Javascript
在vue.js中使用JSZip实现在前端解压文件的方法
2018/09/05 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
jquery轮播图插件使用方法详解
2020/07/31 jQuery
python读取Android permission文件
2013/11/01 Python
wxPython学习之主框架实例
2014/09/28 Python
Python中用sleep()方法操作时间的教程
2015/05/22 Python
python之Socket网络编程详解
2016/09/29 Python
Python实现在线音乐播放器
2017/03/03 Python
python批量赋值操作实例
2018/10/22 Python
django的ORM模型的实现原理
2019/03/04 Python
pytorch获取模型某一层参数名及参数值方式
2019/12/30 Python
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
2017/01/05 HTML / CSS
惠普墨西哥官方商店:HP墨西哥
2016/12/01 全球购物
CheapTickets泰国:廉价航班,查看促销价格并预订机票
2019/12/28 全球购物
英国运动风奢侈品购物网站:Maison De Fashion
2020/08/28 全球购物
学生实习自我鉴定
2013/10/11 职场文书
粗加工管理制度
2014/02/04 职场文书
公司捐款倡议书
2014/05/14 职场文书
技校毕业生自荐信
2014/06/03 职场文书
高中生学习计划书
2014/09/15 职场文书
小学生作文评语集锦
2014/12/25 职场文书
婚礼庆典答谢词
2015/01/20 职场文书
在职证明格式样本
2015/06/15 职场文书
HR在给员工开具离职证明时,需要注意哪些问题?
2019/07/03 职场文书
LeetCode189轮转数组python示例
2022/08/05 Python