各类前后端插件及应用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各类前后端插件及应用相关的知识,希望对你有一定的参考价值。
bxslider 轮播图插件
官网
下载
http://bxslider.com/lib/jquery.bxslider.zip
实例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="jquery.bxslider/jquery.bxslider.css" /> </head> <body> <ul class="bxslider"> <li><img src="images/1.jpg" /></li> <li><img src="images/2.jpg" /></li> <li><img src="images/3.jpg" /></li> <li><img src="images/4.jpg" /></li> </ul> <script src="jquery-1.12.4.js"></script> <script src="jquery.bxslider/jquery.bxslider.js"></script> <script> $(document).ready(function(){ $(‘.bxslider‘).bxSlider(); }); </script> </body> </html>
KindEditor 编辑框插件
官网
下载
http://kindeditor.net/down.php
http://files.cnblogs.com/files/wupeiqi/kindeditor_a5.zip
文件夹说明
├── asp asp示例
├── asp.net asp.net示例
├── attached 空文件夹,放置关联文件attached
├── examples HTML示例
├── jsp java示例
├── kindeditor-all-min.js 全部JS(压缩)
├── kindeditor-all.js 全部JS(未压缩)
├── kindeditor-min.js 仅KindEditor JS(压缩)
├── kindeditor.js 仅KindEditor JS(未压缩)
├── lang 支持语言
├── license.txt License
├── php PHP示例
├── plugins KindEditor内部使用的插件
└── themes KindEditor主题
实例
<textarea name="content" id="content"></textarea> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/plugins/kind-editor/kindeditor-all.js"></script> <script> $(function () { initKindEditor(); }); function initKindEditor() { var kind = KindEditor.create(‘#content‘, { width: ‘100%‘, // 文本框宽度(可以百分比或像素) height: ‘300px‘, // 文本框高度(只能像素) minWidth: 200, // 最小宽度(数字) minHeight: 400 // 最小高度(数字) }); } </script>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <div> <h1>文章内容</h1> {{ request.POST.content|safe }} </div> <form method="POST"> <h1>请输入内容:</h1> {% csrf_token %} <div style="width: 500px; margin: 0 auto;"> <textarea name="content" id="content"></textarea> </div> <input type="submit" value="提交"/> </form> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/plugins/kind-editor/kindeditor-all.js"></script> <script> $(function () { initKindEditor(); }); function initKindEditor() { var a = ‘kind‘; var kind = KindEditor.create(‘#content‘, { width: ‘100%‘, // 文本框宽度(可以百分比或像素) height: ‘300px‘, // 文本框高度(只能像素) minWidth: 200, // 最小宽度(数字) minHeight: 400, // 最小高度(数字) uploadJson: ‘/kind/upload_img/‘, extraFileUploadParams: { ‘csrfmiddlewaretoken‘: ‘{{ csrf_token }}‘ }, fileManagerJson: ‘/kind/file_manager/‘, allowPreviewEmoticons: true, allowImageUpload: true }); } </script> </body> </html>
import os import json import time from django.shortcuts import render from django.shortcuts import HttpResponse def index(request): """ 首页 :param request: :return: """ return render(request, ‘index.html‘) def upload_img(request): """ 文件上传 :param request: :return: """ dic = { ‘error‘: 0, ‘url‘: ‘/static/imgs/20130809170025.png‘, ‘message‘: ‘错误了...‘ } return HttpResponse(json.dumps(dic)) def file_manager(request): """ 文件管理 :param request: :return: """ dic = {} root_path = ‘/Users/wupeiqi/PycharmProjects/editors/static/‘ static_root_path = ‘/static/‘ request_path = request.GET.get(‘path‘) if request_path: abs_current_dir_path = os.path.join(root_path, request_path) move_up_dir_path = os.path.dirname(request_path.rstrip(‘/‘)) dic[‘moveup_dir_path‘] = move_up_dir_path + ‘/‘ if move_up_dir_path else move_up_dir_path else: abs_current_dir_path = root_path dic[‘moveup_dir_path‘] = ‘‘ dic[‘current_dir_path‘] = request_path dic[‘current_url‘] = os.path.join(static_root_path, request_path) file_list = [] for item in os.listdir(abs_current_dir_path): abs_item_path = os.path.join(abs_current_dir_path, item) a, exts = os.path.splitext(item) is_dir = os.path.isdir(abs_item_path) if is_dir: temp = { ‘is_dir‘: True, ‘has_file‘: True, ‘filesize‘: 0, ‘dir_path‘: ‘‘, ‘is_photo‘: False, ‘filetype‘: ‘‘, ‘filename‘: item, ‘datetime‘: time.strftime(‘%Y-%m-%d %H:%M:%S‘, time.gmtime(os.path.getctime(abs_item_path))) } else: temp = { ‘is_dir‘: False, ‘has_file‘: False, ‘filesize‘: os.stat(abs_item_path).st_size, ‘dir_path‘: ‘‘, ‘is_photo‘: True if exts.lower() in [‘.jpg‘, ‘.png‘, ‘.jpeg‘] else False, ‘filetype‘: exts.lower().strip(‘.‘), ‘filename‘: item, ‘datetime‘: time.strftime(‘%Y-%m-%d %H:%M:%S‘, time.gmtime(os.path.getctime(abs_item_path))) } file_list.append(temp) dic[‘file_list‘] = file_list return HttpResponse(json.dumps(dic))
XSS过滤特殊标签
pip3 install beautifulsoup4
#!/usr/bin/env python # -*- coding:utf-8 -*- from bs4 import BeautifulSoup class XSSFilter(object): __instance = None def __init__(self): # XSS白名单 self.valid_tags = { "font": [‘color‘, ‘size‘, ‘face‘, ‘style‘], ‘b‘: [], ‘div‘: [], "span": [], "table": [ ‘border‘, ‘cellspacing‘, ‘cellpadding‘ ], ‘th‘: [ ‘colspan‘, ‘rowspan‘ ], ‘td‘: [ ‘colspan‘, ‘rowspan‘ ], "a": [‘href‘, ‘target‘, ‘name‘], "img": [‘src‘, ‘alt‘, ‘title‘], ‘p‘: [ ‘align‘ ], "pre": [‘class‘], "hr": [‘class‘], ‘strong‘: [] } @classmethod def instance(cls): if not cls.__instance: obj = cls() cls.__instance = obj return cls.__instance def process(self, content): soup = BeautifulSoup(content, ‘lxml‘) # 遍历所有HTML标签 for tag in soup.find_all(recursive=True): # 判断标签名是否在白名单中 if tag.name not in self.valid_tags: tag.hidden = True if tag.name not in [‘html‘, ‘body‘]: tag.hidden = True tag.clear() continue # 当前标签的所有属性白名单 attr_rules = self.valid_tags[tag.name] keys = list(tag.attrs.keys()) for key in keys: if key not in attr_rules: del tag[key] return soup.renderContents() if __name__ == ‘__main__‘: html = """<p class="title"> <b>The Dormouse‘s story</b> </p> <p class="story"> <div name=‘root‘> Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister c1" style=‘color:red;background-color:green;‘ id="link1"><!-- Elsie --></a> <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tilffffffffffffflie</a>; and they lived at the bottom of a well. <script>alert(123)</script> </div> </p> <p class="story">...</p>""" v = XSSFilter.instance().process(html) print(v)
#!/usr/bin/env python # -*- coding:utf-8 -*- from bs4 import BeautifulSoup class XSSFilter(object): __instance = None def __init__(self): # XSS白名单 self.valid_tags = { "font": [‘color‘, ‘size‘, ‘face‘, ‘style‘], ‘b‘: [], ‘div‘: [], "span": [], "table": [ ‘border‘, ‘cellspacing‘, ‘cellpadding‘ ], ‘th‘: [ ‘colspan‘, ‘rowspan‘ ], ‘td‘: [ ‘colspan‘, ‘rowspan‘ ], "a": [‘href‘, ‘target‘, ‘name‘], "img": [‘src‘, ‘alt‘, ‘title‘], ‘p‘: [ ‘align‘ ], "pre": [‘class‘], "hr": [‘class‘], ‘strong‘: [] } def __new__(cls, *args, **kwargs): """ 单例模式 :param cls: :param args: :param kwargs: :return: """ if not cls.__instance: obj = object.__new__(cls, *args, **kwargs) cls.__instance = obj return cls.__instance def process(self, content): soup = BeautifulSoup(content, ‘lxml‘) # 遍历所有HTML标签 for tag in soup.find_all(recursive=True): # 判断标签名是否在白名单中 if tag.name not in self.valid_tags: tag.hidden = True if tag.name not in [‘html‘, ‘body‘]: tag.hidden = True tag.clear() continue # 当前标签的所有属性白名单 attr_rules = self.valid_tags[tag.name] keys = list(tag.attrs.keys()) for key in keys: if key not in attr_rules: del tag[key] return soup.renderContents() if __name__ == ‘__main__‘: html = """<p class="title"> <b>The Dormouse‘s story</b> </p> <p class="story"> <div name=‘root‘> Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister c1" style=‘color:red;background-color:green;‘ id="link1"><!-- Elsie --></a> <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tilffffffffffffflie</a>; and they lived at the bottom of a well. <script>alert(123)</script> </div> </p> <p class="story">...</p>""" obj = XSSFilter() v = obj.process(html) print(v)
随机验证码
创建随机验证码图片
依赖Pillow、字体文件
安装Pillow: pip3 install Pillow
#!/usr/bin/env python # -*- coding:utf-8 -*- import random from PIL import Image, ImageDraw, ImageFont, ImageFilter _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z _upper_cases = _letter_cases.upper() # 大写字母 _numbers = ‘‘.join(map(str, range(3, 10))) # 数字 init_chars = ‘‘.join((_letter_cases, _upper_cases, _numbers)) def create_validate_code(size=(120, 30), chars=init_chars, img_type="GIF", mode="RGB", bg_color=(255, 255, 255), fg_color=(0, 0, 255), font_size=18, font_type="Monaco.ttf", length=4, draw_lines=True, n_line=(1, 2), draw_points=True, point_chance=2): """ @todo: 生成验证码图片 @param size: 图片的大小,格式(宽,高),默认为(120, 30) @param chars: 允许的字符集合,格式字符串 @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG @param mode: 图片模式,默认为RGB @param bg_color: 背景颜色,默认为白色 @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF @param font_size: 验证码字体大小 @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf @param length: 验证码字符个数 @param draw_lines: 是否划干扰线 @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效 @param draw_points: 是否画干扰点 @param point_chance: 干扰点出现的概率,大小范围[0, 100] @return: [0]: PIL Image实例 @return: [1]: 验证码图片中的字符串 """ width, height = size # 宽高 # 创建图形 img = Image.new(mode, size, bg_color) draw = ImageDraw.Draw(img) # 创建画笔 def get_chars(): """生成给定长度的字符串,返回列表格式""" return random.sample(chars, length) def create_lines(): """绘制干扰线""" line_num = random.randint(*n_line) # 干扰线条数 for i in range(line_num): # 起始点 begin = (random.randint(0, size[0]), random.randint(0, size[1])) # 结束点 end = (random.randint(0, size[0]), random.randint(0, size[1])) draw.line([begin, end], fill=(0, 0, 0)) def create_points(): """绘制干扰点""" chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100] for w in range(width): for h in range(height): tmp = random.randint(0, 100) if tmp > 100 - chance: draw.point((w, h), fill=(0, 0, 0)) def create_strs(): """绘制验证码字符""" c_chars = get_chars() strs = ‘ %s ‘ % ‘ ‘.join(c_chars) # 每个字符前后以空格隔开 font = ImageFont.truetype(font_type, font_size) font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / 3, (height - font_height) / 3), strs, font=font, fill=fg_color) return ‘‘.join(c_chars) if draw_lines: create_lines() if draw_points: create_points() strs = create_strs() # 图形扭曲参数 params = [1 - float(random.randint(1, 2)) / 100, 0, 0, 0, 1 - float(random.randint(1, 10)) / 100, float(random.randint(1, 2)) / 500, 0.001, float(random.randint(1, 2)) / 500 ] img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大) return img, strs
通过check_code返回图片的obj和随机字符串
将图片保存,并将随机字符串保存到session中
再通过BytesIO将生成的图片保存到内存中
from utils.check_code import create_validate_code def check_code(request): """ 验证码 :param request: :return: """ stream = BytesIO() img, code = create_validate_code() img.save(stream,‘PNG‘) request.session[‘CheckCode‘] = code return HttpResponse(stream.getvalue())
简单判断用户输入
class Login(View): """ 登录 """ def get(self, request): return render(request, ‘login.html‘) def post(self, request): code = request.POST.get(‘check_code‘) if code.upper() == request.session[‘CheckCode‘].upper(): print(‘验证码正确‘) else: print(‘验证码错误‘) return render(request, ‘login.html‘)
思路
结合session
check_code.py(依赖Pillow、字体)
点击更换时,要将src属性后面+?,这里可以通过js或jQuery实现
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> <link rel="stylesheet" href="/static/css/edmure.css"/> <link rel="stylesheet" href="/static/css/commons.css"/> <link rel="stylesheet" href="/static/css/account.css"/> <style> </style> </head> <body> <div class="login"> <div style="font-size: 25px; font-weight: bold;text-align: center;"> 用户登录 </div> <form role="form" action="/login.html" method="POST"> {% csrf_token %} <div class="form-group"> <label for="username">用户名</label> <input type="text" class="form-control" placeholder="请输入用户名"> </div> <div class="form-group"> <label for="password">密码</label> <input type="password" class="form-control" placeholder="请输入密码"> </div> <div class="form-group"> <label for="password">验证码</label> <div class="row"> <div class="col-xs-7"> <input type="text" class="form-control" placeholder="请输入验证码" name="check_code"> </div> <div class="col-xs-5"> <img src="/check_code.html" onclick="changeCheckCode(this);"> <!-- <img src="/static/imgs/avatar/20130809170025.png"> --> </div> </div> </div> <div class="checkbox"> <label> <input type="checkbox"> 一个月内自动登录 </label> <div class="right"> <a href="#">忘记密码?</a> </div> </div> <button type="submit" class="btn btn-default">登 录</button> </form> </div> <script> function changeCheckCode(ths){ ths.src = ths.src + ‘?‘; } </script> </body> </html>
// 点击验证码图片进行更换 $(function () { $("#code_img").click(function () { var url = $(this).attr("src"); var new_url = url + "?"; $(this).attr("src", new_url); }); });
自定义分页
XSS
有下面一段代码,想将这段代码中的字符串渲染到HTML页面中,默认Django是不能这样去操作的
def user_list(request): page_str = """ <a href="/user_list/?p=1">1</a> <a href="/user_list/?p=2">2</a> <a href="/user_list/?p=3">3</a> """ return render(request, "user_list.html", {"page_str": page_str})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for item in li %} {% include "li.html" %} {% endfor %} </ul> <div> {{ page_str }} </div> </body> </html>
<li>{{ item }}</li>
渲染后的页面只能以字符串的形式显示我们传入的HTML代码
Django认为这存在危险,可能会存在代码被注入的可能,我们可以通过下面两种方式解决
模板的方式
{{ page_str|safe }}
视图方式
from django.utils.safestring import mark_safe def user_list(request): page_str = """ <a href="/user_list/?p=1">1</a> <a href="/user_list/?p=2">2</a> <a href="/user_list/?p=3">3</a> """ page_str = mark_safe(page_str) return render(request, "user_list.html", {"page_str": page_str})
分页1
from django.conf.urls import url from django.contrib import admin from django.conf.urls import include from app01 import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^user_list/‘, views.user_list), ]
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. from django.urls import reverse from django.utils.safestring import mark_safe LIST = [] for i in range(109): LIST.append(i) def user_list(request): current_page = request.GET.get("p", 1) current_page = int(current_page) start = (current_page - 1) * 10 end = current_page * 10 data = LIST[start:end] # 总个数 all_count = len(LIST) # 取商、余数 count, y = divmod(all_count, 10) if y: count += 1 page_list = [] for i in range(1, count+1): if i == current_page: temp = ‘<a class="page active" href="/user_list/?p=%s">%s</a>‘ % (i, i) else: temp = ‘<a class="page" href="/user_list/?p=%s">%s</a>‘ % (i, i) page_list.append(temp) page_str = "".join(page_list) page_str = mark_safe(page_str) return render(request, "user_list.html", {"li": data, "page_str": page_str})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .pagination .page{ display: inline-block; padding: 5px; background-color: cyan; margin: 5px; } .pagination .page.active{ background-color: brown; color: black; } </style> </head> <body> <ul> {% for item in li %} {% include "li.html" %} {% endfor %} </ul> <div class="pagination"> {{ page_str }} </div> </body> </html>
分页2
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. from django.urls import reverse from django.utils.safestring import mark_safe LIST = [] for i in range(1009): LIST.append(i) def user_list(request): current_page = request.GET.get("p", 1) # 当前页数 current_page = int(current_page) per_page_count = 10 start = (current_page - 1) * per_page_count end = current_page * per_page_count data = LIST[start:end] # 总个数 all_count = len(LIST) # 取商、余数 total_count, y = divmod(all_count, per_page_count) if y: total_count += 1 page_list = [] pager_num = 11 if total_count < pager_num: start_index = 1 end_index = total_count + 1 else: if current_page <= (pager_num+1)/2: start_index = 1 end_index = pager_num + 1 else: start_index = current_page - (pager_num-1)/2 end_index = current_page + (pager_num+1)/2 if (current_page + (pager_num-1)/2) > total_count: end_index = total_count + 1 start_index = total_count - pager_num + 1 if current_page == 1: prev = ‘<a class="page" href="#">上一页</a>‘ else: prev = ‘<a class="page" href="/user_list/?p=%s">上一页</a>‘ % (current_page - 1) page_list.append(prev) for i in range(int(start_index), int(end_index)): if i == current_page: temp = ‘<a class="page active" href="/user_list/?p=%s">%s</a>‘ % (i, i) else: temp = ‘<a class="page" href="/user_list/?p=%s">%s</a>‘ % (i, i) page_list.append(temp) if current_page == total_count: nex = ‘<a class="page" href="#">下一页</a>‘ else: nex = ‘<a class="page" href="/user_list/?p=%s">下一页</a>‘ % (current_page + 1) page_list.append(nex) jump = """ <input type=‘text‘ /><a id=‘ii1‘ onclick=‘jumpTo(this, "/user_list/?p=");‘>GO</a> <script> function jumpTo(ths, base){ var val = ths.previousSibling.value; location.href = base + val; } </script> """ page_list.append(jump) page_str = "".join(page_list) page_str = mark_safe(page_str) return render(request, "user_list.html", {"li": data, "page_str": page_str})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .pagination .page{ display: inline-block; padding: 5px; background-color: cyan; margin: 5px; } .pagination .page.active{ background-color: brown; color: black; } </style> </head> <body> <ul> {% for item in li %} {% include "li.html" %} {% endfor %} </ul> <div class="pagination"> {{ page_str }} </div> </body> </html>
分页3
from django.conf.urls import url from django.contrib import admin from django.conf.urls import include from app01 import views urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^user_list/‘, views.user_list), ]
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. from django.urls import reverse from utils import pagination LIST = [] for i in range(1009): LIST.append(i) def user_list(request): current_page = request.GET.get("p", 1) current_page = int(current_page) page_obj = pagination.Page(current_page, len(LIST)) data = LIST[page_obj.start:page_obj.end] page_str = page_obj.page_str("/user_list/") return render(request, "user_list.html", {"li": data, "page_str": page_str})
在工程目录创建目录utils,然后在此目录中创建pagination.py文件
pagination.py
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author: JiaChen from django.utils.safestring import mark_safe # 封装分页模块 class Page(object): def __init__(self, current_page, data_count, per_page_count=10, pager_num=7): self.current_page = current_page self.data_count = data_count self.per_page_count = per_page_count self.pager_num = pager_num @property def start(self): return (self.current_page - 1) * self.per_page_count @property def end(self): return self.current_page * self.per_page_count @property def total_count(self): v, y = divmod(self.data_count, self.per_page_count) if y: v += 1 return v def page_str(self, base_url): page_list = [] if self.total_count < self.pager_num: start_index = 1 end_index = self.total_count + 1 else: if self.current_page <= (self.pager_num + 1) / 2: start_index = 1 end_index = self.pager_num + 1 else: start_index = self.current_page - (self.pager_num - 1) / 2 end_index = self.current_page + (self.pager_num + 1) / 2 if (self.current_page + (self.pager_num - 1) / 2) > self.total_count: end_index = self.total_count + 1 start_index = self.total_count - self.pager_num + 1 if self.current_page == 1: prev = ‘<a class="page" href="#">上一页</a>‘ else: prev = ‘<a class="page" href="%s?p=%s">上一页</a>‘ % (base_url, self.current_page - 1) page_list.append(prev) for i in range(int(start_index), int(end_index)): if i == self.current_page: temp = ‘<a class="page active" href="%s?p=%s">%s</a>‘ % (base_url, i, i) else: temp = ‘<a class="page" href="%s?p=%s">%s</a>‘ % (base_url, i, i) page_list.append(temp) if self.current_page == self.total_count: nex = ‘<a class="page" href="#">下一页</a>‘ else: nex = ‘<a class="page" href="%s?p=%s">下一页</a>‘ % (base_url, self.current_page + 1) page_list.append(nex) jump = """ <input type=‘text‘ /><a id=‘ii1‘ onclick=‘jumpTo(this, "%s?p=");‘>GO</a> <script> function jumpTo(ths, base){ var val = ths.previousSibling.value; location.href = base + val; } </script> """ % base_url page_list.append(jump) page_str = "".join(page_list) page_str = mark_safe(page_str) return page_str
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .pagination .page{ display: inline-block; padding: 5px; background-color: cyan; margin: 5px; } .pagination .page.active{ background-color: brown; color: black; } </style> </head> <body> <ul> {% for item in li %} {% include "li.html" %} {% endfor %} </ul> <div class="pagination"> {{ page_str }} </div> </body> </html>
以上是关于各类前后端插件及应用的主要内容,如果未能解决你的问题,请参考以下文章