第39章 Django调用验证码
在保持不修改Django框架源代码的基准下,只好通过ajax调用captcha库返回验证码了。可惜vue.js不支持ajax功能,但好在有axios等第3方插件助力。
39.1 安装axios
要想使用axios插件,可以通过npm指令进行安装或直接引入cdn地址。注意:大部分操作系统本身是不支持npm指令,它可通过安装node.js获得。
使用 npm:
npm install axios
使用 cdn:
<script src='https://unpkg.com/axios/dist/axios.min.js'></script>
39.2 应用axios
不懂偷懒的程序猿不是好工程师,我喜欢偷懒,喜欢用cdn的方式。打开templates/ admin/login.html文件,在引入login.js的上一行,加入引入axios的代码。另外在表单(form.errors)错误提示信息的下方,加入验证码错误提示的代码;在输入密码框的下方,加入输入验证码的的代码,还有一个隐藏hashkey的hiddle,自己找找看。
{% load i18n static simpletags %}{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}<!DOCTYPE html><html lang='{{ LANGUAGE_CODE|default:'en-us' }}' {% if LANGUAGE_BIDI %}dir='rtl'{% endif %}><head> <meta charset='UTF-8'> <meta name='renderer' content='webkit'> <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'> <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1'> <title>{{ site_title }}-{% trans 'Log in' %}</title> <link rel='icon' href='{% static '/admin/simpleui-x/img/favicon.png' %}'> {% if 'SIMPLEUI_STATIC_OFFLINE'|get_config %} <link rel='stylesheet' href='{% static '/admin/simpleui-x/elementui/theme-chalk/index.css' %}'> <link rel='stylesheet' href='{% static '/admin/simpleui-x/fontawesome-free-5.8.1-web/css/all.min.css' %}'> {% else %} <link rel='stylesheet' href='https://unpkg.com/element-ui/lib/theme-chalk/index.css'> <link rel='stylesheet' href='https://cdn.bootcss.com/font-awesome/5.8.1/css/all.min.css'> {% endif %} <link rel='stylesheet' href='{% static '/admin/simpleui-x/css/login.css' %}?_=2.1'> <style type='text/css'> .bg { background: #f0f2f5; background-image: url('{% static '/admin/simpleui-x/img/bg.svg' %}'); min-height: 100%; background-repeat: no-repeat; background-position: 50%; background-size: 100%; padding: 20px 0; position: relative; } </style> {% block head %} {# You can add code here. #} {% endblock %}</head><body class='bg'><div class='login-main'> {% block logo %} <div class='logo'> {% if 'SIMPLEUI_LOGO'|get_config %} <img src='{{ 'SIMPLEUI_LOGO'|get_config |safe }}'> {% else %} <img src='{% static '/admin/simpleui-x/img/logo.png' %}'> {% endif %} </div> {% endblock %} {% block header %} <div class='header'>{{ site_header }}</div> {% endblock %} {% block errors %} {% if form.non_field_errors %} {% for error in form.non_field_errors %} <el-alert title='{{ error }}' type='error'> </el-alert> {% endfor %} {% endif %} {% if form.errors and not form.non_field_errors %} <p class='errornote'> {% if form.errors.items|length == 1 %} <el-alert title='{% trans 'Please correct the error below.' %}' type='error'></el-alert> {% else %} <el-alert title='{% trans 'Please correct the errors below.' %}' type='error'></el-alert> {% endif %} </p> {% endif %} <el-alert v-if='show_error' title='验证码错误' type='error'></el-alert> {% endblock %} {% block form %} <form class='simpleui-form' action='{{ app_path }}' method='post' id='login-form'> {% csrf_token %} <div class='simpleui-input-inline'> <el-input prefix-icon='fas fa-user' v-model='username' name='username' placeholder='{% trans 'username' %}'></el-input> </div> <div class='simpleui-input-inline'> <el-input prefix-icon='fas fa-lock' type='password' v-model='password' name='password' placeholder='{% trans 'password' %}' show-password></el-input> </div> <div class='simpleui-input-inline'> <el-input prefix-icon='fas el-icon-s-help' v-model='captcha' name='captcha' placeholder='验证码'> <img slot='append' :src='img_url' @click='refresh()'/> </el-input> </div> <div class='simpleui-input-inline login-btn'> <el-button :icon='loading?'el-icon-loading':''' @click='login()' type='primary'>{% trans 'Log in' %}</el-button> </div> <input id='hashkey' type='hidden' v-model='hashkey' name='hashkey'/> <input type='hidden' name='next' value='{{ next }}'/> </form> {% endblock %}</div>{% if 'SIMPLEUI_STATIC_OFFLINE'|get_config %} <script type='text/javascript' src='{% static '/admin/simpleui-x/js/vue.min.js' %}'></script> <script type='text/javascript' src='{% static '/admin/simpleui-x/elementui/index.js' %}'></script>{% else %} <script src='https://cdn.jsdelivr.net/npm/vue'></script> <script src='https://unpkg.com/element-ui/lib/index.js'></script>{% endif %} <script src='https://unpkg.com/axios/dist/axios.min.js'></script> <script type='text/javascript' src='{% static '/admin/simpleui-x/js/login.js' %}?_=2.3'></script>{% if 'SIMPLEUI_LOGIN_PARTICLES'|get_config != False %}<style type='text/css'> #particles-js{ position: fixed; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: -1; } </style><!-- particles.js container --><div id='particles-js'></div><script type='text/javascript' src='{% static '/admin/simpleui-x/particles/particles.js' %}'></script><script type='text/javascript' src='{% static '/admin/simpleui-x/particles/app.js' %}'></script>{% endif %}</body></html>
39.3 调用验证码
在模板文件上的添油加醋,只是对验证码进行一番造势而已,如果没有真材实料,最终火不过3天,活不到第二集。我说的是什么,你懂得。打开static/simpleui-x/js/login.js,调整内容如下。
if (parent.callback) { //如果是在子框架内就把首页刷新 parent.callback();}new Vue({ el: '.login-main', data: { username: '', password: '', captcha:'', hashkey:'', img_url:'', show_error: false, loading: false }, created: function () { this.get_captcha(); },methods: {refresh:function () { this.get_captcha(); }, login: function () { hash_key = this.hashkey; captcha_str = this.captcha; this.loading = true; this.show_error = false; var that = this; axios.get('/special/check_captcha/', { params: { hash_key: hash_key, captcha_str: captcha_str } } ).then(function (response) { var json = JSON.parse(JSON.stringify(response.data)); var result = json['result']; if (result) { document.getElementById('login-form').submit(); } else { that.loading = false; that.show_error = true; } }) }, get_captcha: function () { var that=this; axios.get('/special/captcha/') .then(function (response) { var result = JSON.parse(JSON.stringify(response.data)); that.hashkey = result['hashkey']; that.img_url = result['image_url']; }) } , }})
辛苦了好久,我也想早点见到效果(图),有效果才有成就,有效果,才有说服力。
赞 (0)