zoukankan      html  css  js  c++  java
  • 使用HttpHandler实现图片验证码

    打开VS,添加一般处理程序(.ashx)。默认已经实现了IHttpHandler里的ProcessRequest方法和IsReusable属性,只需改变ProcessRequest里的方法即可。

    (注:在此引用的是袁老师和张老师的例子,写出来呢,主要是学习)

    袁老师:http://www.cnblogs.com/xdesigner/archive/2008/06/04/1213496.html

    如果对验证码原理还不是很清楚的,请看看袁老师的链接。

    张老师:http://www.cnblogs.com/JimmyZhang/archive/2007/09/15/894124.html

     //方法一:
    <%@ WebHandler Language="C#" class="Handler" %>

    using System;
    using System.Web;
    using System.Web.SessionState;
    using System.Drawing;
    using System.Text;
    using System.Drawing.Imaging;

    public class Handler : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "image/gif";
            //建立Bitmat对象,绘图
            Bitmap basemap = new Bitmap(200, 60);
            Graphics graph = Graphics.FromImage(basemap);
            graph.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60);
            Font font = new Font(FontFamily.GenericSansSerif, 48, FontStyle.Bold, GraphicsUnit.Pixel);
            Random r = new Random();
            string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string letter;
            StringBuilder s = new StringBuilder();
            //添加随机的五个字母
            for (int i = 0; i < 5; i++)
            {
                letter = letters.Substring(r.Next(0, letters.Length - 1), 1);
                s.Append(letter);
                graph.DrawString(letter, font, new SolidBrush(Color.Black), i * 38, r.Next(0, 15));
            }
            //混淆背景
            Pen linePen = new Pen(new SolidBrush(Color.Black), 2);
            for (int i = 0; i < 6; i++)
            {
                graph.DrawLine(linePen, new Point(r.Next(0, 199), r.Next(0, 59)), new Point(r.Next(0, 199), r.Next(0, 59)));
            }
            //将图片保存到输出流中
            basemap.Save(context.Response.OutputStream, ImageFormat.Gif);
            context.Session["CheckCode"] = s.ToString();//如果没有实现IRequiresSessionState,则这里会出错,也无法生成图片
            context.Response.End();
        } 
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    添加测试页面:

    前台:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>无标题页</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <p align="center">
                <font face="宋体" size="6">ASP.NET验证码测试页面</font></p>
            <font face="宋体">验证码:
                <asp:TextBox ID="txtCheckCode" runat="server" Width="224px"></asp:TextBox>
                <img src="Handler.ashx" alt="图片验证码" ondblclick="this.src = 'Handler.ashx?flag=' + Math.random() "
                    style="border: 2px;" />
                <!--
          这里的 ondblclick 代码中采用一个毫无意义的flag参数可有效的防止浏览器缓存图片
          使得显示的验证码图片一定是最新的图片
         -->
                <span>看不清楚,双击图片换一张。</span>
             </font>
             <p>
            <asp:Button ID="cmdOK" runat="server" Text="点击得到上一个验证码" OnClick="cmdOK_Click"></asp:Button>
            </p>
            <asp:Label ID="lblResult" runat="server"></asp:Label>
        </div>
        </form>
    </body>
    </html>

     后台:

    using System;
    using System.Data;

    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {}
        protected void cmdOK_Click(object sender, EventArgs e)
        {
            if (System.Web.HttpContext.Current.Session["CheckCode"] != null)
            {
                lblResult.Text = System.Web.HttpContext.Current.Session["CheckCode"] as string;
            }
        }
    }

    结果:

     

    //方法二:
    <%@ WebHandler Language="C#" class="Handler" %>

    using System;
    using System.Web;
    using System.Web.SessionState;
    using System.Drawing;
    using System.Text;
    using System.Drawing.Imaging;

    public class Handler : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {

            // 创建一个包含随机内容的验证码文本
            Random rand = new Random();
            int len = rand.Next(4, 6);
            char[] chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
            StringBuilder myStr = new StringBuilder();
            for (int iCount = 0; iCount < len; iCount++)
            {
                myStr.Append(chars[rand.Next(chars.Length)]);
            }
            string text = myStr.ToString();
            Size ImageSize = Size.Empty;
            Font myFont = new Font("MS Sans Serif", 20);
            // 计算验证码图片大小
            using (Bitmap bmp = new Bitmap(10, 10))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    SizeF size = g.MeasureString(text, myFont, 10000);
                    ImageSize.Width = (int)size.Width + 1;
                    ImageSize.Height = (int)size.Height + 1;
                }
            }
            // 创建验证码图片
            using (Bitmap bmp = new Bitmap(ImageSize.Width, ImageSize.Height))
            {
                // 绘制验证码文本
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.Clear(Color.White);
                    using (StringFormat f = new StringFormat())
                    {
                        f.Alignment = StringAlignment.Near;
                        f.LineAlignment = StringAlignment.Center;
                        f.FormatFlags = StringFormatFlags.NoWrap;
                        g.DrawString(
                            text,
                            myFont,
                            Brushes.Black,
                            new RectangleF(
                            0,
                            0,
                            ImageSize.Width,
                            ImageSize.Height),
                            f);
                    }
                }

                // 制造噪声 杂点面积占图片面积的 30%
                int num = ImageSize.Width * ImageSize.Height * 30 / 100;

                for (int iCount = 0; iCount < num; iCount++)
                {
                    // 在随机的位置使用随机的颜色设置图片的像素
                    int x = rand.Next(ImageSize.Width);
                    int y = rand.Next(ImageSize.Height);
                    int r = rand.Next(255);
                    int g = rand.Next(255);
                    int b = rand.Next(255);
                    Color c = Color.FromArgb(r, g, b);
                    bmp.SetPixel(x, y, c);
                }

                // 输出图片
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                context.Response.ContentType = "image/Gif";
                context.Session["CheckCode"] = text;
                ms.WriteTo(context.Response.OutputStream);
                ms.Close();
            }
            myFont.Dispose();
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

     测试页面同上。

    注:从本质上讲,两种方法是一样的,在此只是让自己多明白理解而已。

  • 相关阅读:
    干掉你的老板(小游戏)
    SEO优化数据系列表(图)
    javascript动态加载三
    javascript动态加载二
    截屏
    vimdiff
    pscp scp ftp samba windows send files to linux
    login windows 10 with passwd instead of pin
    modify requirements.txt
    整片注释 ,shell
  • 原文地址:https://www.cnblogs.com/zuoguanglin/p/2367286.html
Copyright © 2011-2022 走看看