职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 2111|回复: 0

AJAX+jsp无刷新验证码实例

[复制链接]
梦段桥 发表于 2007-1-23 21:59 | 显示全部楼层 |阅读模式
【导读】本文通过实例,介绍在做验证码的时候为了给用户很好的体验,需要在原有验证方式基础之上增加一段js,通过xmlhttp来获取返回值,以此来验证是否有效。同时,本例还特别适合检验用户名是否有效。  


1、我们在做验证码的时候往往由于要反作弊,验证有时故意加入多的干扰因素,这时验证码显示不很清楚,用户经常输入错误。这样不但要重新刷新页面,导致用户没有看清楚验证码而重填而不是修改,而且如果没有用session保存下用户输入的其它数据的话(如姓名),用户刚刚输入的内容也不存在了,这样给用户造成不好的体验。  

2、本例在原有验证方式基础之上增加一段js,通过xmlhttp来获取返回值,以此来验证是否有效,这样即使用户浏览器不支持js,也不会影响他的正常使用了。  

3、为了防止作弊,当用户连接3次输入错误时则重载一下图片,这样也利于用户因为图片上的验证码辨认不清而使其终无法输入正确。  

4、本例还特别适合检验用户名是否有效,只要从后台做个sql查询,返回一个值或是xml即可。(这种例子太多  ,就在此不赘述了)。  

5、本例的优点在于非常方便用户输入,而且减少对服务器端的请求,可以说既改善用户体验而且略会节省带宽成本,但相应地要在页面上增加一段JavaScript代码,在目前网速越来越快人们要求便捷舒适的今天,似乎我们更应注意提供给用户良好的使用感受。  

代码如下:  

1、img.jsp,输入主页面  

程序代码:
<%@ page contentType=\\\"text/html; charset=GBK\\\" language=\\\"java\\\"

import=\\\"java.sql.*\\\" errorPage=\\\"\\\" pageEncoding=\\\"GBK\\\"%>

<%

//set Chinese Char

//Cody by JarryLi@gmail.com ;

//homepage:jiarry.126.com

request.setCharacterEncoding(\\\"GBK\\\");

response.setCharacterEncoding(\\\"GBK\\\");

response.setContentType(\\\"text/html; charset=GBK\\\");

%>

<html>

<head>

<title>图片验证</title>

<meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=gb2312\\\">

<script src=\\\"net.js\\\"></script>

</head>

<body>

AJAX(无刷新及时提示)验证码实例!cody by jarry

<hr>

<%

String num=request.getParameter(\\\"num\\\");

String random=(String)session.getAttribute(\\\"random\\\");

String name=request.getParameter(\\\"name\\\");

if(num!=null&&random!=null&&name!=null)

{

if(num.equals(random))

{

out.println(\\\"<font style=\\\\\"color:green;font-weight:bold\\\\\">

恭喜您,验证码输入成功,这里是提交结果页面,可以写入数据库了!</font>

<a href=\\\\\"img.jsp\\\\\">返回再测试</a><br>\\\");

out.println(\\\"您的名字是:\\\"+name);

out.println(\\\"<br>\\\");

out.println(\\\"您输入的是:\\\"+num);

out.println(\\\"验证码是:\\\"+random);

out.println(\\\"</body>\\\");

return;//javascript:history.go(-1)

}

}

%>

<script type=\\\"text/javascript\\\">

var times=0;

function subform(){

var gtext=this.req.responseText;

var info=document.getElementById(\\\"info\\\");

if(gtext.indexOf(\\\"validate_successful\\\")!=-1){

//info.innerHTML=\\\"<font color=green>验证码通过</font>\\\";

document.forms[\\\"myform\\\"].submit();

//当得到的值表示合法,则验证码通过。

}else{

times++;

if(times>=3){//如果连接3次输入错误,则重载图片,可以防止作弊和用户看不清图片;

info.innerHTML=\\\"接连3次输入错误。更新验证码,请重新输入\\\";

document.forms[\\\"myform\\\"].num.value=\\\"\\\";

show(document.getElementById(\'random\'));

times=0;

}else{

info.innerHTML=\\\"第\\\"+times+\\\"次验证码错误,请注意区分大小写 \\\";

}

document.forms[\\\"myform\\\"].num.select();

}

}

function validata(obj){

var enter=true;

var info=document.getElementById(\\\"info\\\");

var msg=\\\"\\\";

if(obj.name.value.match(/^\\s*$/g)){//如果未输入名字,提示

msg+=\\\"请输入您的姓名<br>\\\";enter=false

}

if(obj.num.value.match(/^\\s*$/g)){//如果未输入验证码,提示

msg+=\\\"请输入验证码<br>\\\";enter=false

}

if(enter==false){

info.innerHTML=msg;

return false;

}

var url=\\\"num.jsp?num=\\\"+obj.num.value;

var newxmlhttp=new net.ContentLoader(url,subform,\\\"\\\",\\\"get\\\",null,null);

return false;

}

function show(o){

//重载验证码

var timenow = new Date().getTime();

o.src=\\\"random.jsp?d=\\\"+timenow;

/*

//超时执行;

setTimeout(function(){

o.src=\\\"random.jsp?d=\\\"+timenow;

}

,20);

*/

}

</script>

<form action=\\\"img.jsp\\\" name=\\\"myform\\\" method=\\\"post\\\"

onsubmit=\\\"return validata(this);\\\">

您的姓名:<input type=\\\"text\\\" name=\\\"name\\\" size=10> (为了更好地说明此例,特加姓名一项)<br>

验 证 码:<input type=\\\"text\\\" name=\\\"num\\\" size=10 maxlength=\\\"4\\\">

<img src=\\\"random.jsp\\\" id=\\\"random\\\" align=\\\"\\\" valign=\\\"absmiddle\\\" hspace=\\\"5\\\">

<a href=\\\"javascript:show(document.getElementById(\'random\'))\\\">验证码看不清</a><br>

<br> <input type=\\\"submit\\\" value=\\\" 提交 \\\"><br>

<div id=info style=\\\"color:red;padding:10px;font-size:12px;\\\"></div>

</form>

</body>

</html>  



2、num.jsp,反馈xmlhttp请求的页面  

程序代码:
<%@ page contentType=\\\"text/html; charset=GBK\\\" language=\\\"java\\\"

import=\\\"java.sql.*\\\" errorPage=\\\"\\\" pageEncoding=\\\"GBK\\\"%>

<%

//set Chinese Char

//Cody by JarryLi@gmail.com ;

//homepage:jiarry.126.com

request.setCharacterEncoding(\\\"GBK\\\");

response.setCharacterEncoding(\\\"GBK\\\");

response.setContentType(\\\"text/html; charset=GBK\\\");

%>

<%

String num=request.getParameter(\\\"num\\\");

String random=(String)session.getAttribute(\\\"random\\\");

if(num!=null&&random!=null)

{

if(!num.equals(random))

{

/*

out.println(\\\"<script>alert(\'验证码错误!请重试。\')</script>\\\");

out.println(\\\"<script>history.go(-1)</script>\\\");

//response.sendRedirect(\\\"img.jsp\\\");

*/

out.print(\\\"validate_failed:\\\"+random);

}

else

{

//out.println(\\\"<center>验证成功!</center>\\\");

out.print(\\\"validate_successful:\\\"+random);

}

}

%>  



3、random.jsp,生成验证码图片的页面  

程序代码:
<%@ page autoFlush=\\\"false\\\" import=\\\"java.util.*,java.awt.*,

java.awt.image.*,com.sun.image.codec.jpeg.*,java.util.*\\\" %>

<%

//set Chinese Char

//Cody by JarryLi@gmail.com ;

//homepage:jiarry.126.com

request.setCharacterEncoding(\\\"GBK\\\");

response.setCharacterEncoding(\\\"GBK\\\");

response.setContentType(\\\"text/html; charset=GBK\\\");

%>

<%

String chose=\\\"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\\";

char display[]={\'0\',\' \',\'0\',\' \',\'0\',\' \',\'0\'},ran[]={\'0\',\'0\',\'0\',\'0\'},temp;

Random rand=new Random();

for(int i=0;i<4;i++)

{

temp=chose.charAt(rand.nextInt(chose.length()));

display[i*2]=temp;

ran=temp;

}



String random=String.valueOf(display);

session.setAttribute(\\\"random\\\",String.valueOf(ran));

%>

<%

out.clear();

response.setContentType(\\\"image/jpeg\\\");

response.addHeader(\\\"pragma\\\",\\\"NO-cache\\\");

response.addHeader(\\\"Cache-Control\\\",\\\"no-cache\\\");

response.addDateHeader(\\\"Expries\\\",0);

int width=80, height=30;

BufferedImage image = new BufferedImage(width, height,

BufferedImage.TYPE_INT_RGB);

Graphics g = image.getGraphics();

//以下填充背景颜色

g.setColor(Color.GREEN);

g.fillRect(0, 0, width, height);

//设置字体颜色

g.setColor(Color.RED);

Font font=new Font(\\\"Arial\\\",Font.PLAIN,20);

g.setFont(font);

//g.drawString(random,5,14);

g.drawString(random,5,20);

g.dispose();

ServletOutputStream outStream = response.getOutputStream();

JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(outStream);

encoder.encode(image);

outStream.close();

%>  




4、net.js,封装好的xmlhttp对象,可以很方便的调用  

程序代码:

/* namespacing object */

var net=new Object();



net.READY_STATE_UNINITIALIZED=0;

net.READY_STATE_LOADING=1;

net.READY_STATE_LOADED=2;

net.READY_STATE_INTERACTIVE=3;

net.READY_STATE_COMPLETE=4;

/*--- content loader object for cross-browser requests ---*/

net.ContentLoader=function(url,on_load,on_error,method,params,contentType){

this.req=null;

this.on_load=on_load;

this.on_error=(on_error) ? on_error : this.defaultError;

this.loadXMLDoc(url,method,params,contentType);

}

net.ContentLoader.prototype.loadXMLDoc=function(url,method,params,contentType){

if (!method)

{

method=\\\"GET\\\";

}

if (!contentType && method==\\\"OST\\\")

{

contentType=\'application/x-www-form-urlencoded\';

}

if (window.XMLHttpRequest)

{

this.req=new XMLHttpRequest();

}

else if (window.ActiveXObject)

{

//add try catch;

try {

this.req = new ActiveXObject(\\\"Msxml2.XMLHTTP\\\");

}catch (e1){

try {

this.req = new ActiveXObject(\\\"Microsoft.XMLHTTP\\\");

} catch (e2){

}

}

//

//this.req=new ActiveXObject(\\\"Microsoft.XMLHTTP\\\");

}

if (this.req)

{

try

{

var loader=this;

this.req.onreadystatechange=function()

{

net.ContentLoader.onReadyState.call(loader);

}

this.req.open(method,url,true);

if (contentType)

{

this.req.setRequestHeader(\'Content-Type\', contentType);

}

this.req.send(params);

}

catch (err)

{

this.on_error.call(this);

}

}

}

net.ContentLoader.onReadyState=function(){

var req=this.req;

var ready=req.readyState;

if (ready==net.READY_STATE_COMPLETE){

var httpStatus=req.status;

if (httpStatus==200 || httpStatus==0){

this.on_load.call(this);

}else{

this.on_error.call(this);

}

}

}

net.ContentLoader.prototype.defaultError=function(){

alert(\\\"error fetching data!\\\"

+\\\"\\n\\nreadyState:\\\"+this.req.readyState

+\\\"\\nstatus: \\\"+this.req.status

+\\\"\\nheaders: \\\"+this.req.getAllResponseHeaders());

}
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-10 20:56 , Processed in 0.114037 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表