直接上传原码,大家自己去慢慢理解吧。该文章只是讲解了验证码的简单实现和原理,希望大家通过它设计出更绚丽的界面。
如有不对的地方希望大家指正。
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;
}
}
}
}
完成以上过程就可以产生简单的验证码登陆界面了。希望对有需要的朋友其他抛砖引玉的作用。