风舞的博客
谁曾看见风舞,云袖澄素,倩影飘忽。谁曾伤心的恸哭,翠酒寒烛,紫檀香柱。
     谁又流传了千古,魅异高孤,幽鬼其独。谁又追寻了苦苦,挥不去美丽的灵狐。
posts - 3,comments - 23,trackbacks - 0

    Ajax是目前很时髦也很酷的一个技术,为此小弟也曾花上数月时间研究,并已成功运用到实际的项目中.感觉运用好的话确实能带来非常棒的用户体验,反之则会使你深陷在js代码的泥潭中,不但得不到预期的效果,代码也会变的臃肿丑陋,得不偿失.而登录验证很可能是你学Ajax时拿来练手的第一个或第二个例子,在这里小弟也贴一个本人初学Ajax时写的一段代码(已经重写,从SAJAX迁移到了prototype.js),希望能与志同道合之人共同学习、共同进步。
    废话不说了,先贴代码:

<?php
/**************************************************************
 * login.php
 * @author 风舞
 * @email wjiujun (at) gmail.com
 * @note ajax登录验证,用户名和密码保存在客户端cookies中
 **************************************************************/

//得到安全字符串
function safe_str($str)
{
    return (string)htmlspecialchars(trim($str));
}

if(safe_str($_GET['action'])=='login')
{
 //登录验证
    header("Content-type: text/xml");
 $user=safe_str($_POST['user']);
 $pwd=safe_str($_POST['pwd']);

 $response_xml='<info>';

 //只有当用户名为root,密码为888时才通过验证
 $response_xml.=($user!='root'||$pwd!='888')?'<error>incorrect username or password!</error>':"<login><info><user>{$user}</user><pwd>{$pwd}</pwd></info></login>";

 $response_xml.='</info>';
 print $response_xml;
 exit;
}
else
{
?>
<html>
<head>
<title>Ajax登录验证</title>
<script type="text/javascript" src="prototype.js"></script>
<script language="JavaScript" type="text/javascript">
<!--
 //得到cookies的值
 function getCookie(name)
 {
  var dc=document.cookie;
  var prefix=name+"=";
  var begin=dc.indexOf("; "+prefix);

  if(begin==-1)
  {
   begin=dc.indexOf(prefix);
   if(begin!=0)
    return "";
  }
  else
   begin+=2;
  var end=document.cookie.indexOf(";",begin);
  if(end==-1)
   end=dc.length;
  return unescape(dc.substring(begin+prefix.length,end));
 }

 //删除cookies
 function delCookie(name)
 {
  if(getCookie(name))
   document.cookie=name+"=; path=/; expires=Thu, 01-Jan-70 00:00:01 GMT";
 }

 //设置cookies
 function setCookie(name,value)
 {
  var expires=new Date();
  expires.setTime(expires.getTime()+30*24*60*60*1000); //设置cookies失效时间为一个月
  document.cookie=name+"="+escape(value)+"; expires="+expires.toGMTString()+"; path=/";
 }

 //得到节点的值
 function getElementTextNS(local,parentElem,index)
 {
  var result = parentElem.getElementsByTagName(local)[index];
  return result?result.childNodes.length>1?result.childNodes[1].nodeValue:(result.firstChild?result.firstChild.nodeValue:""):"n/a";
 }

 //初始化
 function init()
 {
  var loginUser=getCookie("ajaxUser");
  var loginPwd=getCookie("ajaxPwd");
  loginUser!=""?parseLogin(loginUser,loginPwd):genLoginForm();
 }

 //退出登录
 function logOut()
 {
  delCookie("ajaxUser");
  delCookie("ajaxPwd");
  genLoginForm();
 }

 //用指定的用户名和密码登录
 function parseLogin(username,password)
 {
  var postBody="user="+escape(username)+"&pwd="+escape(password);
  new Ajax.Request("?action=login", {method:"post", postBody:postBody,
      onFailure:function() {alert("程序异常")}, 
      onSuccess:makeResult});
  return false;
 }

 //处理登录返回结果
 function makeResult(response)
 {
  var info=response.responseXML.getElementsByTagName("info");
  var error=getElementTextNS("error",info[0],0);
  if(error!="n/a")
  {
   genLoginForm();
   alert("请输入正确的用户名和密码");
  }
  else
  {
   var user=getElementTextNS("user",info[0],0);
   var pwd=getElementTextNS("pwd",info[0],0);

   setCookie("ajaxUser",user);
   setCookie("ajaxPwd",pwd);
   if(getCookie("ajaxUser")=="")
   {
    genLoginForm();
    alert("您的浏览器必须支持cookies");
   }
   else
    $("content").innerHTML="<h2>Hello,<font color=\"red\">"+user+"</font>!<a href=\"javascript:logOut();\">logout</a></h2>";
  }
 }

 //显示登录框
 function genLoginForm()
 {
  $("content").innerHTML="<form onsubmit=\"return parseLogin($('user').value,$('pwd').value);\">用户名:<input type=\"text\" id=\"user\" size=\"12\"> 密码:<input type=\"password\" id=\"pwd\" size=\"12\"> <input type=\"submit\" value=\"登录\"></form>";
 }
//-->
</script>
</head>

<body onload="init();">
<div id="content"></div>
</body>
</html>
<?php
}
?>

    程序的思路主要是:页面加载时调用init判断客户端是否存有网站所需的cookies,如果有的话取相应cookies到服务端验证,通过验证显示成功提示,反之显示登录框,同样如果没有所需cookies也显示登录框直到用户输入正确的用户名和密码。整个过程两次用到了ajax,一次是用户输入用户名和密码点击登录按钮后,另一次是页面加载时的用户名和密码验证,其实两个过程调用的是同一个函数parseLogin,这个函数主要负责与远程(也就是“?action=login”)通讯,“?action=login”接受post过来的用户名和密码进行处理并返回处理结果,客户端收到服务端的处理结果后进行进一步的处理(调用函数makeResult)。可以看出与传统的“处理登录”相比是有很大差别的,首先整个过程中没有任何的页面加载(也就是无刷新),form中我并没有指定action和method,由js完成与PHP的通信,同时也是异步的(你可以同时进行多个请求,而按传统方式在进行一个请求时不能再进行其他请求(使用多个iframe也可以模拟出异步的效果,这里不包括这种情况)),充分利用这两点就可以制作出以前需要通过非常复杂的方法才可能达到的效果,如自动完成等。
    客户端使用的prototype.js,实际上从我第一眼发现这个强悍无比的家伙时就离不了它了,还狠心“抛弃”了已经很习惯的SAJAX。另外服务端返回的是XML,在这里使用XML只是想说明一种通用的js处理XML的方式。
    当然由于是无刷新的,所以在提交登录时已经看不到状态栏上的进度条,如果登录时间过长,用户可能不知道发生了什么事情,会不停的点击提交,这时我们一般会在提交时生成一个加载条,告诉用户目前正在发生什么,如gmail右上角的loading...,chinaren的“我正在帮您登录,请稍等...”,当服务端返回结果时就要隐藏这个加载条,控制display属性就可以简单的实现这种轮换效果。

posted on 2006-08-30 22:24 风舞 阅读(9410) 评论(9)  编辑 收藏 引用 网摘 所属分类: js/ajax

FeedBack:
# re: 经典的Ajax示例----登录验证
2006-08-31 16:53 | neatstudio
小伙子有前途  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2006-08-31 21:11 | 风舞
@enze
prototype.js比较轻量级,应用范围较广,而且基于prototype.js的库比较多,是目前很多js库的鼻祖,只是不太习惯Ruby风格的语法,呵呵,另外,看到你的留言了,在评论时好像是不好插入代码的(在后台发日志时有插入代码这个功能的):-)  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2006-09-01 16:14 | enze
这个AJAX类库是封装好了的,如果你觉得有必要扩展也可以的啦。调用超简单的。  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2006-10-16 20:30 | 张家界旅游网
不错。。正在学习ajax中。。这样的文章越多越好。。  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2007-04-09 17:15 | bill
谢谢分享。  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2007-11-02 16:32 | guest
面加载时的用户名和密码验证有必要用ajax吗?
php直接读取不就行了
如果lz只是想做个例子还可以理解  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2008-03-28 23:03 |
法的规定非官方的  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2008-03-28 23:03 |
该广告古古怪怪古古怪怪  回复  更多评论
  
# re: 经典的Ajax示例----登录验证
2008-07-18 13:48 | fds
df  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: