php js 验证码,js实现验证码的方法

验证码的生命周期

在web应用中,验证码常用于登录注册。验证码本质就是一张图片。

我们来看一下验证码的生命周期:客户端请求验证码

服务端渲染验证码:渲染一张包含随机字符串的图片

随机字符串写入session

读取图片并返回响应客户端提交:显示响应(即验证码图片)

获取用户输入字符串

提交用户输入服务端验证:取出session中保存的随机字符串与用户提交的字符串进行对比

字符串信息一致,进行下一步处理

字符串信息不一致,返回错误信息

下面我们在Django中实践以上流程。

验证码实践新建一个名为ValidCode的Django项目,并创建应用app01,配置路由如下:

from django.conf.urls import urlfrom app01 import views

urlpatterns = [

url(r'^test/$', views.test),

url(r'^valid_code/$', views.valid_code),

]定义test视图函数,当客户端访问http://127.0.0.1:8000/test/时,返回test.html页面;当客户端提交提交数据时,取出session中保存的验证码与用户提交的字符串进行对比:

from django.shortcuts import render, HttpResponse, redirectdef test(request):

if request.method == 'GET':

return render(request, 'test.html')

code1 = request.session['valid_code']

code2 = request.POST.get('valid_code')

if code1 == code2:

return HttpResponse('OK')

else:

return redirect('/test/')

{% csrf_token %}

验证码:

validPic刷新

验证

var refresh = document.getElementsByClassName('refresh')[0];

var validPic = document.getElementsByTagName('img')[0];

refresh.onclick = function () {

validPic.src += "?"; //利用img标签的特性,刷新验证码

}

说明:test.html中标签的属性:src="/valid_code/",表示向http://127.0.0.1:8000/valid_code/发起get 请求,以获取图片

点击刷新标签,执行validPic.src += "?",以重新获取图片(刷新验证码)定义valid_code视图函数,将验证码写入session中,并返回验证码:

def valid_code(request):

with open('bilibili.jpg', 'rb')as f:

res = f.read()

valid_code = 'bilibili'

request.session["valid_code"] = valid_code

return HttpResponse(res)

说明:验证码本质就是一张图片,这里就先返回一张图片吧。。。浏览器访问http://127.0.0.1:8000/test/:

400af943013d8f799fbee3a6aec7d52e.png

说明:显示以上页面其实有两次get请求:对/test/发起get请求,服务端返回test.html页面;

test.html页面中标签的属性:src="/valid_code/",对/valid_code/发起get请求,服务端返回一张图片

提交验证码:输入'bilibili',显示‘OK',否则重定向到当前页面,略。

生成随机验证码

这样似乎就成了,不过实际应用中的验证码都是随机生成的。而上面的验证码不论怎么刷新,也不会变,服务端始终返回一张静态图片。那么有没有办法呢?有,用pillow画图模块,每次请求过来,服务端实时渲染一张包含随机字符串的图片。下面我们改写valid_code函数:

def valid_code(request):

from PIL import Image, ImageDraw, ImageFont

from io import BytesIO # 内存管理,优化速度

import random

img = Image.new(mode='RGB', size=(120, 30),

color=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))) # 创建图像对象(模式,大小,颜色)

draw = ImageDraw.Draw(img, mode='RGB') # 创建画笔(图像对象,模式)

font = ImageFont.truetype("app01/static/fonts/kumo.ttf", 28) # 读取字体(字体路径,字体大小)

code_list = [] for i in range(5):

char = random.choice([chr(random.randint(65, 90)), str(random.randint(1, 9))])

code_list.append(char)

draw.text([i * 24, 0], char, (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),

font=font) # 通过画笔的text方法,为图像绘制字符串(位置,文本,颜色,字体)

# [i * 24, 0] 字体坐标,i*24设置水平偏移,让每个字符分开显示

f = BytesIO() # 拿到一个内存文件句柄f

img.save(f, "png") # 保存图像对象到f

valid_code = ''.join(code_list)

request.session["valid_code"] = valid_code # 验证码写入session

return HttpResponse(f.getvalue()) # `getvalue()`方法拿到内存文件句柄的内容

说明:使用前需要先安装pillow模块:pip install pillow

绘制的图像可以保存的磁盘上,但是速度慢,这里使用内存管理from io import BytesIO,优化速度

f = BytesIO() 拿到一个内存文件句柄

f.getvalue()拿到内存文件句柄的内容

注意,Django的session信息默认存在数据库,使用session前应先执行数据库迁移,以生成django_session表现在重新访问http://127.0.0.1:8000/test/:

118012786c77731ba1632b478527c0a1.png

验证码已经是实时生成的了,并且每次点击刷新,显示一张新的图片。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区间数多属性决策matlab,区间数多属性决策的改进理想解法

Interval Multiple Attribute Decision Making Based on the Improved Technique for Order Preference by Similarity to Ideal Solution1、School of Economics and Management, Southwest Jiaotong University2、Deaprtment of Mathematics, North Sichuan Medical CollegeA…

.NET 标准介绍

本文介绍如何使用 .NET 标准,更容易地实现向 .NET Core 迁移。文中会讨论计划包含的 APIs,跨构架兼容性如何工作以及这对 .NET Core 意味着什么。 如果你对细节感兴趣,这篇文章正是为你准备的;如果你没有那么多时间或者对细节并不…

HTTP 返回码详解

转载自 HTTP 返回码详解200 服务器成功返回网页 404 请求的网页不存在 503 服务不可用1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码。 100(继续)请求者应当继续提出请求。 服务器返回此代码表示已收到请求…

银行营业网点管理系统——entity类(Branches)

package BranchesMgr.entity; /*** * author Administrator*网点信息表*/ public class Branches {private int id;private String name;private int cityAreatyid;private String cityName;public String getCityName() {return cityName;}public void setCityName(String cit…

自己的php工具,用PHP自己编写的站长工具箱

前沿: 看到站长之家的站长工具很强大,所以也想自己试着实现一些其中的功能,由于本人只具有初阶的php技术,所以便用php一些函数实现了部分功能。主要功能包括:正则表达式测试工具,MD5和SHA1加密工具&#xf…

轻量级的web框架[Nancy On .Net Core Docker]

.net core现在已经有了大的发展,虽然笔者现在已经从事python开发,但是一直在关注.net的发展,在逛博客园的时候,发现有大家都会提到Nancy这个框架,在简单的使用之后,发现竟然是如此的简单而优雅 public cla…

Git使用中的一些奇技淫巧

转载自 Git使用中的一些奇技淫巧Git作为当今最流行的分布式代码版本管理系统,它的出现改变了软件的开发流程,大大地提高了开发流畅度。 本人使用Git也有一段时间了,一直都只是使用一些最最基本的几个命令,对于不复杂的代码工程来…

oracle 更新参数,Oracle动态、静态参数参数修改规则

首先,查看要修改的oracle参数的属性(动态or静态)SQL> select name,value,isses_modifiable,issys_modifiable from V$PARAMETER where namemax_dump_file_size;注:isses_modifiable 为Y,session级别修改的参数,SQL>alter se…

银行营业网点管理系统——entity类(CityArea)

package BranchesMgr.entity; /*** 城区表* author Administrator**/ public class CityArea {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(Stri…

漫画:如何用Zookeeper实现分布式锁?

转载自 漫画:如何用Zookeeper实现分布式锁?什么是临时顺序节点?让我们来回顾一下Zookeeper节点的概念:Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Znode。Znode分为四种类型&#…

使用CoreProfiler/NanoProfiler实现跨平台amp;应用的整合性能调试

NanoProfiler是一个开源.NET性能调试类库,CoreProfiler是其.NET Core版本的实现。在之前的一些文章中,我曾介绍过NanoProfiler的主要使用方式,以及如何为生产环境,基于ELK对应用性能进行调试和监控。不过,对于一般的用…

oracle授权序列,oracle 第二集序列

方案一:直接授权法1.用happyy2165登录,之后,授权grant select on HAPPYY2165.STUDENT to scott2.用scott登录,用如下代码去访问Student表select * from HAPPYY2165.student方式二:通过角色去控制1.自定义角色 role_tes…

两种播放m3u8链接的方法

两种播放m3u8链接的方法 置顶 2018年12月21日 10:38:10 Saddyの云 阅读数:15200 本文将提供两种方法介绍如何播放m3u8链接 第一种是添加浏览器插件 Native HLS Playback ,此处以Firefox举例(谷歌浏览器也可以用这个插件,苹果电脑自带浏览器…

漫画:什么是ZooKeeper

转载自 漫画:什么是ZooKeeperZookeeper的数据模型Zookeeper的数据模型是什么样子呢?它很像数据结构当中的树,也很像文件系统的目录。树是由节点所组成,Zookeeper的数据存储也同样是基于节点,这种节点叫做Znode。但是&a…

异步性能:了解 Async 和 Await 的成本

异步编程长时间以来一直都是那些技能高超、喜欢挑战自我的开发人员涉足的领域 — 这些人愿意花费时间,充满热情并拥有心理承受能力,能够在非线性的控制流程中不断地琢磨回调,之后再回调。 随着 Microsoft .NET Framework 4.5 的推出&#xff…

什么叫做在oracle目录下,ORACLE directory 目录

Create directory让我们可以在Oracle数据库中灵活的对文件进行读写操作,极大的提高了Oracle的易用性和可扩展性。其语法为:CREATE [OR REPLACE] DIRECTORY directory AS pathname;本案例具体创建如下:create or replace directory exp_dir as /tmp;目录创建以后&…

银行营业网点管理系统——dao包(BaseDao)

package BranchesMgr.dao; /*** 数据库操作类* author Administrator**/ import java.sql.*; import java.util.List; public class BaseDao {Connection connnull;PreparedStatement psnull;ResultSet rsnull;public void getConnection(){try {Class.forName("com.micro…