直接上传原码,大家自己去慢慢理解吧。该文章只是讲解了验证码的简单实现和原理,希望大家通过它设计出更绚丽的界面。
如有不对的地方希望大家指正。
1、css文件checkcode.css (定义验证码图片的显示大小)
#CheckCode{ float:left;}
.x-form-code{width:73px;height:20px;vertical-align:middle;cursor:pointer; float:left; margin-left:7px;}
2、html文件(建立登陆页面)
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>V3系统登陆</title>
<link rel="stylesheet" type="text/css" href="/extjs4/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="/CSS/css.css" />
<link rel="stylesheet" type="text/css" href="/CSS/checkcode.css" />
<script type="text/javascript" src="/extjs4/locale/ext-lang-zh_CN.js"></script>
<script type="text/javascript" src="/extjs4/ext-all.js"></script>
<script type="text/javascript" src="/js/v3login.js"></script>
<style type="text/css">body{
background-image:url(/images/eg_bg_06.gif);
background-repeat: repeat
}
</style>
</head>
<body>
</body>
</html>
3、Extjs文件 v3login.js (Extjs的具体实现,登陆采用Form的形式)
Ext.BLANK_IMAGE_URL = 'images/s.gif'; Ext.define('myCheckCode',{ extend: 'Ext.form.field.Text', alias: 'widget.checkcode', inputTyle:'codefield', codeUrl:Ext.BLANK_IMAGE_URL, isLoader:true, onRender:function(ct,position){ this.callParent(arguments); this.codeEl = ct.createChild({ tag: 'img', src: Ext.BLANK_IMAGE_URL}); this.codeEl.addCls('x-form-code'); this.codeEl.on('click', this.loadCodeImg, this); if (this.isLoader) this.loadCodeImg(); }, alignErrorIcon: function() { this.errorIcon.alignTo(this.codeEl, 'tl-tr', [2, 0]); }, loadCodeImg: function() { this.codeEl.set({ src: this.codeUrl + '?id=' + Math.random() }); } }) var checkcode = Ext.create('myCheckCode',{ cls : 'key', fieldLabel : '验证码', name : 'CheckCode', id : 'CheckCode', allowBlank : false, isLoader:true, blankText : '验证码不能为空', codeUrl: '/ckc.ashx', //labelStyle: 'font-weight:bold;padding:0', labelWidth:70, //height:70, labelAlign: 'right', width : 150 }) var Login = function(){ var Login_Form = Ext.create('Ext.form.Panel', { id:'Login_Form', frame: true, //layout: 'anchor', //该form分为两列 bodyPadding: 5, baseCls: "x-plain", //指定使用系统背景色 //defaults: { anchor: "95%", msgTarget: "side" }, fieldDefaults: { labelAlign: 'left' //labelWidth: 90, //anchor: '100%' }, items:[{ xtype: 'fieldcontainer', labelStyle: 'font-weight:bold;padding:0', width:400, height:100, x:-40, y:-8, labelWidth: 300, labelHeight:100, readOnly:true, style:{ background: '#ffffff url(/images/logintop.jpg) no-repeat left center', //no-repeat paddingLeft: '30px' //20px }, fieldLabel: '' },{ xtype: 'fieldcontainer', labelStyle: 'font-weight:bold;padding:0', width:300, labelWidth: 250, disabled:false, readOnly:true, fieldStyle:'color:red;', //disabled:true, fieldLabel: '请输入帐号信息' },{ id:'UserID', xtype: 'textfield', name: 'UserID', //blankText: '请输入帐号。。。', width:230, labelWidth: 70, allowBlank: false, labelAlign: 'right', disabled:false, readOnly:false, msgTarget: 'side', //regex: /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/, //regexText: 'Email 格式不正确', emptyText: '请输入帐号。。。', //fieldStyle:'background:red;', fieldLabel: '帐号' },{ id:'UserPwd', //blankText: '请输入密码。。。', xtype: 'textfield', name: 'UserPwd', //字段名 width:230, allowBlank: false, inputType: 'password', labelWidth: 70, labelAlign: 'right', msgTarget: 'side', emptyText: '请输入密码。。。', //anchor: '100%', fieldLabel: '密码' //显示名称 },checkcode ] }) var Login_Form_Win = Ext.create('Ext.Window', { title: '登陆窗口', closeAction: 'hide', //改变系统关闭键的方法为'hide' width: 300, //300 height: 300, //250 minWidth: 50, minHeight: 50, maximizable: false, //是否显示最大化按钮 modal: true, plain: true, //可以强制窗体颜色各背景色变的一样 layout: 'fit', closable:false, //显示关闭键 //resizable:false, //是否可以改变窗口大小 items:Login_Form, fieldDefaults: { xtype: 'textfield' }, listeners:{ "show":function() { Login_Form.getForm().reset(); } }, buttonAlign:'center', buttons: [{ text: '登陆', handler:function(){ if (Login_Form.getForm().isValid()) { //判断提交的数据是否符合正则表达式 Login_Form.getForm().submit({ clientValidation: true, waitTitle: '提示', //标题 waitMsg: '正在登陆请稍后...', //提示信息 url: 'ashx/login.ashx', params: { 'UserID': Login_Form.getForm().findField('UserID').getValue() ,'UserPwd':Login_Form.getForm().findField('UserPwd').getValue() ,'CheckCode':Login_Form.getForm().findField('CheckCode').getValue() }, method: "POST", success: function (form, action) { var ret = Ext.JSON.decode(action.response.responseText); if (ret.success){ //成功后 if (ret.msg=='OK'){ Login_Form_Win.hide(); window.location.href = 'default.aspx'; //打开主页 } else{ Ext.Msg.show({ title: '错误提示', msg: ret.msg, buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR }); } } else{ Ext.Msg.show({ title: '错误提示', msg: ret.msg, buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR }); }; }, failure: function (form, action) { var errorObj = Ext.JSON.decode(action.response.responseText); Ext.Msg.show({ title: '错误提示', msg: errorObj.msg, buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR }); } }) } else { alert('出错!输入数据格式出错 !'); } } }, { text: '重置 ', handler: function () { Login_Form.getForm().reset(); } }] }); Login_Form_Win.show(); } Ext.onReady(function(){ Ext.QuickTips.init(); Ext.BLANK_IMAGE_URL = 'images/s.gif'; Login(); });
4、验证码产生 C# 文件 CKC.ashx.cs (产生图片文件,返回图片格式,并且把验证码保存在session中用来判断,当然也可以保存在cookies中)
using System; using System.Web; using System.Drawing; namespace V3WEB { /// <summary> /// CKC 的摘要说明 /// </summary> public class CKC : IHttpHandler, System.Web.SessionState.IRequiresSessionState { //产生验证码的字符集(去除I 1 l L,O 0等易混字符) public string charSet = "2,3,4,5,6,8,9,A,B,C,D,E,F,G,H,J,K,M,N,P,R,S,U,W,X,Y"; public void ProcessRequest(HttpContext context) { string validateCode = CreateRandomCode(4); //context.Response.Cookies.Add(new HttpCookie("CheckCode", checkCode));//保存到Cookies 里 context.Session["CheckCode"] = validateCode; //保存到Session中 CreateImage(validateCode, context); } public bool IsReusable { get { return false; } } /// <summary> /// 生成验证码 /// </summary> /// <param name="n">位数</param> /// <returns>验证码字符串</returns> private string CreateRandomCode(int n) { string[] CharArray = charSet.Split(','); string randomCode = ""; int temp = -1; Random rand = new Random(); for (int i = 0; i < n; i++) { if (temp != -1) { rand = new Random(i * temp * ((int)DateTime.Now.Ticks)); } int t = rand.Next(CharArray.Length - 1); if (temp == t) { return CreateRandomCode(n); } temp = t; randomCode += CharArray[t]; } return randomCode; } private void CreateImage(string checkCode, HttpContext context) { int iwidth = (int)(checkCode.Length * 13); System.Drawing.Bitmap image = new System.Drawing.Bitmap(iwidth, 23); Graphics g = Graphics.FromImage(image); Font f = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Italic | System.Drawing.FontStyle.Bold)); // 前景色 Brush b = new System.Drawing.SolidBrush(Color.Black); // 背景色 g.Clear(Color.White); // 填充文字 g.DrawString(checkCode, f, b, 0, 1); // 随机线条 Pen linePen = new Pen(Color.Gray, 0); Random rand = new Random(); for (int i = 0; i < 5; i++) { int x1 = rand.Next(image.Width); int y1 = rand.Next(image.Height); int x2 = rand.Next(image.Width); int y2 = rand.Next(image.Height); g.DrawLine(linePen, x1, y1, x2, y2); } // 随机点 for (int i = 0; i < 30; i++) { int x = rand.Next(image.Width); int y = rand.Next(image.Height); image.SetPixel(x, y, Color.Gray); } // 边框 g.DrawRectangle(new Pen(Color.Gray), 0, 0, image.Width - 1, image.Height - 1); // 输出图片 System.IO.MemoryStream ms = new System.IO.MemoryStream(); image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); context.Response.ClearContent(); context.Response.ContentType = "image/Jpeg"; context.Response.BinaryWrite(ms.ToArray()); g.Dispose(); image.Dispose(); } } }
5、登陆判断C# login.ashx
using System; using System.Collections.Generic; using System.Web.SessionState; using System.Web; using BLL.System; using Model; using System.Data; namespace V3WEB.ashx { /// <summary> /// login 的摘要说明 /// </summary> public class login : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { Comm_Grant_UserBLL obj = new Comm_Grant_UserBLL(); string _JsonData = null; int count = 0; if (context.Session["CheckCode"].ToString().ToUpper() != context.Request["CheckCode"].ToString().ToUpper()) { _JsonData = "{success:true,msg:'出错!验证码错误!'}"; } else { try { string _userid = context.Request["UserID"].ToString(); string _userpwd = context.Request["UserPwd"].ToString(); DataTable u = obj.getIsRight(_userid, _userpwd); if (u.Rows.Count > 0) { context.Session["UserID"] = u.Rows[0]["UserID"].ToString(); context.Session["UserName"] = u.Rows[0]["UserName"].ToString(); context.Session["Login"] = "Yes"; count = 1; } else { count = 0; } if (count == 1) { _JsonData = "{success:true,msg:'OK'}"; } else { _JsonData = "{success:true,msg:'用户或密码错误!'}"; } } catch (Exception e) { _JsonData = "{success:false,msg:'" + e.Message + "'}"; } } context.Response.ContentType = "text/plain"; // "text/plain"; context.Response.Write(_JsonData); context.Response.End(); } public bool IsReusable { get { return false; } } } }
完成以上过程就可以产生简单的验证码登陆界面了。希望对有需要的朋友其他抛砖引玉的作用。