此代碼是須要依賴:css
sanic==19.9.0html
Pillow==7.0.0git
馬哥教育Python網絡班企業教練思路:npm
import randomimport stringimport uuidimport base64import platformfrom PIL import Image, ImageDraw,ImageFontfrom io import BytesIOfrom sanic import Sanicfrom sanic.response import HTTPResponse,textfrom sanic.views import HTTPMethodView
app = Sanic()
session = {}
class VerifyCode: def __init__(self, numbers:int): """ 指定:生成的數量 """ self.number = numbers
def draw_lines(self, draw, num, width, height): """劃線"""
x1 = random.randint(0, width / 2) y1 = random.randint(0, height / 2) x2 = random.randint(0, width) y2 = random.randint(height / 2, height) draw.line(((x1, y1), (x2, y2)), fill='black', width=1)
def random_color(self): """隨機顏色""" return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)) def gene_text(self): """生成驗證碼""" return "".join(random.sample(string.ascii_letters+string.digits, self.number))
def get_verify_code(self): """ draw.text(): 文字的繪製,第一個參數指定繪製的起始點(文本的左上角所在位置),第二個參數指定文本內容,第三個參數指定文本的顏色,第四個參數指定字體(經過ImageFont類來定義) """ code = self.gene_text() width, height = 130, 30 im = Image.new("RGB", (width, height), "white") sysstr = platform.system() font = None if sysstr == "Windows": font = ImageFont.truetype("C:\WINDOWS\Fonts\STXINGKA.TTF", 25) elif sysstr == "Darwin": font = ImageFont.truetype('/Library/Fonts/AppleMyungjo.ttf', 25) draw = ImageDraw.Draw(im) for item in range(self.number): draw.text((5+random.randint(-5,5)+23*item, 5+random.randint(-5, 5)), text=code[item], fill=self.random_color(), font=font) self.draw_lines(draw, self.number, width, height) return im, code
class SimpleView(HTTPMethodView): body = """ <html> <head> <meta charset="UTF-8"> <title>登陸</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- 可選的 Bootstrap 主題文件(通常不用引入) --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </head> <body> <form class="form-inline" method="post" action="/code"> <div> <div class="form-group">{error} </div> <div class="form-group"> <label for="exampleInputName2">驗證碼</label> <input type="text" class="form-control" id="captcha" name="code"> </div> <div class="form-group"> <img src="data:image/jpeg;base64,{base64_data}" class="img-img-rounded"> </div> <div> <button type="submit">驗證</button> </div> </div> </form> </body> </html> """
async def get(self, request): return self.response(error="")
async def post(self, request): uuid = request.cookies.get("uuid", "1") verfy_code = request.form.get("code", "2").lower() code = session.get(uuid, "").lower() if code == verfy_code: return text('驗證碼正確') return self.response(error='<input class="form-control" id="disabledInput" type="text" placeholder="驗證碼錯誤" disabled>')
def response(self, error): im, code = VerifyCode(5).get_verify_code() buf = BytesIO() im.save(buf, "jpeg") buf_str = buf.getvalue() base64_data = base64.b64encode(buf_str).decode() id = uuid.uuid1().__str__() session[id] = code body = self.body.format(base64_data=base64_data, error=error) response = HTTPResponse(body, content_type="text/html; charset=utf-8") response.cookies["uuid"] = id return response
app.add_route(SimpleView.as_view(), '/code')
if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)
簡單的實現了驗證碼,沒有實現點擊刷新,點擊刷新的原理不難:
異步請求+刷新接口就行了,記得更新對應的session的key裏面的value