python web框架Flask实现图形验证码及验证码的动态刷新实例

下列代码都是以自己的项目实例讲述的,相关的文本内容很少,主要说明全在代码注释中

自制图形验证码

这里所说的图形验证码都是自制的图形,通过画布、画笔、画笔字体的颜色绘制而成的。将验证码封装成一个类比较好管理,代码里有绝对详细的注释,当然大家可以直接复制。

里面涉及的字体都是从系统电脑上自带的,大家直接复制当前目录下就可以了。

主目录/utils/captcha/__init__.py

import random

import string

# Image:一个画布

# ImageDraw:一个画笔

# ImageFont:画笔的字体

from PIL import Image, ImageDraw, ImageFont

# Captcha验证码

class Captcha(object):

# 生成4位数的验证码

numbers = 4

# 验证码图片的宽度和高度

size = (100, 30)

# 验证码字体大小

fontsize = 25

# 加入干扰线的条数

line_number = 2

# 构建一个验证码源文本

SOURCE = list(string.ascii_letters)

for index in range(0, 10):

SOURCE.append(str(index))

# 用来绘制干扰线

@classmethod

def __gene_line(cls, draw, width, height):

begin = (random.randint(0, width), random.randint(0, height))

end = (random.randint(0, width), random.randint(0, height))

draw.line([begin, end], fill=cls.__gene_random_color(), width=2)

# 用来绘制干扰点

@classmethod

def __gene_points(cls, draw, point_chance, width, height):

# 大小限在【0, 100】中

chance = min(100, max(0, int(point_chance)))

for w in range(width):

for h in range(height):

tmp = random.randint(0, 100)

if tmp > 100 - chance:

draw.point((w, h), fill=cls.__gene_random_color())

# 生成随机颜色

@classmethod

def __gene_random_color(cls, start=0, end=255):

random.seed()

return (random.randint(start, end),

random.randint(start, end),

random.randint(start, end))

# 随机选择一个字体

@classmethod

def __gene_random_font(cls):

fonts = [

"PAPYRUS.TTF",

"CENTAUR.TTF",

"Inkfree.ttf",

"verdana.ttf",

]

font = random.choice(fonts)

return "utils/captcha/"+font

# 用来随机生成一个字符串(包括英文和数字)

@classmethod

def gene_text(cls, numbers):

# numbers是生成验证码的位数

return " ".join(random.sample(cls.SOURCE, numbers))

# 生成验证码

@classmethod

def gene_graph_captcha(cls):

# 验证码图片的宽高

width, height = cls.size

# 创建图片

image = Image.new("RGBA", (width, height), cls.__gene_random_color(0, 100))

# 验证码的字体

font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)

# 创建画笔

draw = ImageDraw.Draw(image)

# 生成字符串

text = cls.gene_text(cls.numbers)

# 获取字体的尺寸

font_width, font_height = font.getsize(text)

# 填充字符串

draw.text(((width-font_width)/2, (height-font_height)/2),

text, font=font, fill=cls.__gene_random_color(150, 255))

# 绘制干扰线

for x in range(0, cls.line_number):

cls.__gene_line(draw, width, height)

# 绘制干扰点

cls.__gene_points(draw, 10, width, height)

with open("captcha.png", "wb") as fp:

image.save(fp)

return text, image

显示图形验证码

一般图形验证码都是在表单中,这样短时间内的数据及建议保存在redis缓存中(用户点击动态刷新图形验证码)。首先我们绘制图形验证码保存到项目的目录下(入口文件是主目录(项目目录)app.py文件,图片也保存到主目录下),然后通过url地址访问自制的图形验证码(这里我只添加主要的代码)

主目录/common/views.py

@bp.route("/captcha")

def graph_captcha():

"""

使用定义好的图形验证码类,来制作验证码

以验证码为键、验证码为值(为了用户的体验,让其忽略大小写)存储在redis缓存中

通过BytesIO字节流的方式保存和访问图片

:return: 图片响应

"""

# 获取验证码

text, image = Captcha.gene_graph_captcha()

cpcache.set(text.lower(), text.lower())

# BytesIO:字节流

out = BytesIO()

# 保存图片

image.save(out, "png")

# 存储完图片,将文件的指针指向文件头,使下次保存图片能覆盖前面保存的图片,节省空间

out.seek(0)

# 访问图片,并将其作为一个响应返回给前台

resp = make_response(out.read())

resp.content_type = "image/png"

return resp

前端页面的代码如下:

<div class="form-group">

<div class="input-group">

<input type="text" class="form-control" name="graph_captcha" placeholder="图形验证码">

<span class="input-group-addon captcha-addon">

<img id="captcha-img" class="captcha-img" src="{{ url_for("common.graph_captcha") }}" alt="">

</span>

</div>

</div>

动态刷新验证码

无非就是再生成一张图形验证码,通过url再次访问就可以,但是这样做是非常麻烦的,这里我很难解释(很难!!!),大家就直接复制代码吧,这个代码就是点击图片生成一个新的url访问图片

这个文件放在公共的目录下就可以了

var cpparam = {

setParam: function(href, key, value){

//重新加载整个页面

var isReplaced = false;

var urlArray = href.split("?");

if(urlArray.length > 1){

var queryArray = urlArray[1].split("&");

for(var i=0; i < queryArray.length; i++){

var paramArray = queryArray[i].split("=");

if(paramArray[0] == key){

paramArray[1] = value;

queryArray[i] = paramArray.join("=");

isReplaced = true;

break;

}

}

if(!isReplaced){

var params = {};

params[key] = value;

if(urlArray.length > 1){

href = href + "$" + $.param(params);

}else{

href = href + "?" + $.param(params);

}

}else{

var params = queryArray.join("&");

urlArray[1] = params;

href = urlArray.join("?");

}

}else{

var param = {};

param[key] = value;

if(urlArray.length > 1){

href = href + "$" + $.param(param);

}else{

href = href + "?" + $.param(param);

}

}

return href;

}

};

对应html的js文件就需要实现元素(图片)点击刷新图片,调用上面的变量cpparam生成一章图片并访问。

$(function(){

$("#captcha-img").on("click", function(){

var self = $(this);

var src = self.attr("src");

var newsrc = cpparam.setParam(src, "xx", Math.random());

self.attr("src", newsrc);

});

});

以上是 python web框架Flask实现图形验证码及验证码的动态刷新实例 的全部内容, 来源链接: utcz.com/z/323572.html

回到顶部