Python开发【Django】:组合搜索、JSONP、XSS过滤
组合搜索
做博客后台时,需要根据文章的类型做不同的检索
1、简单实现
关联文件:
from django.conf.urls import url
from . import views urlpatterns = [
url(r'^index.html/$',views.index),
url(r'^article/(?P<article_type>\d+)-(?P<category>\d+).html/$',views.article)
]
url.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.condition a{
display:inline-block;
padding: 3px 5px;
border: 1px solid black;
}
.condition a.active{
background-color: brown;
}
</style>
</head>
<body>
<h2>过滤条件</h2> <div class="condition">
{% if kwargs.article_type == 0 %}
<a href="/article/0-{{ kwargs.category }}.html" class="active">全部</a>
{% else %}
<a href="/article/0-{{ kwargs.category }}.html">全部</a>
{% endif %} {% for row in article_type %}
{% if row.id == kwargs.article_type %}
<a class="active" href="/article/{{ row.id }}-{{ kwargs.category }}.html">{{ row.caption }}</a>
{% else %}
<a href="/article/{{ row.id }}-{{ kwargs.category }}.html">{{ row.caption }}</a>
{% endif %}
{% endfor %}
</div> <div class="condition">
{% if kwargs.category == 0 %}
<a class="active" href="/article/{{ kwargs.article_type }}-0.html">全部</a>
{% else %}
<a href="/article/{{ kwargs.article_type }}-0.html">全部</a>
{% endif %} {% for row in category %}
{% if row.id == kwargs.category %}
<a class="active" href="/article/{{ kwargs.article_type }}-{{ row.id }}.html">{{ row.caption }}</a>
{% else %}
<a href="/article/{{ kwargs.article_type }}-{{ row.id }}.html">{{ row.caption }}</a>
{% endif %}
{% endfor %}
</div> <h2>查询结果</h2>
<ul>
{% for row in articles %}
<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type.caption }}]-[{{ row.category.caption }}]</li>
{% endfor %}
</ul>
</body>
</html>
article.html
数据库结构:
from django.db import models # Create your models here. class Categoery(models.Model):
caption = models.CharField(max_length=16) class ArticleType(models.Model):
caption = models.CharField(max_length=16) class Article(models.Model): title = models.CharField(max_length=32)
content = models.CharField(max_length=255) category = models.ForeignKey(Categoery)
article_type = models.ForeignKey(ArticleType)
处理文件:
from . import models
def article(request,*args,**kwargs): search_dict = {}
for key,value in kwargs.items():
kwargs[key] = int(value) # 把字符类型转化为int类型 方便前端做if a == b 这样的比较
if value !='0':
search_dict[key] = value
articles = models.Article.objects.filter(**search_dict) # 字典为空时表示搜索所有 article_type = models.ArticleType.objects.all()
category = models.Categoery.objects.all() return render(request,'article.html',{'articles':articles,
'article_type':article_type,
'category':category ,
'kwargs':kwargs})
注:实现此功能并不难,最重要的是理清里面的思路;首先先要确定url访问路径格式http://127.0.0.1:8000/article/0-0.html ,第一个0表示article_type字段,第二个0表示category字段,如果为零时,表示搜索此字段全部信息,确认好这个,是成功的第一步,处理文件上有检索的处理;第二个关键点是生成字典search_dict进行相关的搜索,如果是0表示搜索全部;第三个关键点,也是很巧妙的一个方式,把参数kwargs再次传到前端,简直神来之笔!
2、另一种尝试(加载内存调优)
由于ArticleType类型是博客定死的数据,后期不会做变动,可以把数据加载到内存当中,加快查询速度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.condition a{
display:inline-block;
padding: 3px 5px;
border: 1px solid black;
}
.condition a.active{
background-color: brown;
}
</style>
</head>
<body>
<h2>过滤条件</h2> <div class="condition">
{% if kwargs.article_type_id == 0 %}
<a href="/article/0-{{ kwargs.category_id }}.html" class="active">全部</a>
{% else %}
<a href="/article/0-{{ kwargs.category_id }}.html">全部</a>
{% endif %} {% for row in article_type%}
{% if row.0 == kwargs.article_type_id %}
<a class="active" href="/article/{{ row.0 }}-{{ kwargs.category_id }}.html">{{ row.1 }}</a>
{% else %}
<a href="/article/{{ row.0 }}-{{ kwargs.category_id }}.html">{{ row.1 }}</a>
{% endif %}
{% endfor %}
</div> <div class="condition">
{% if kwargs.category_id == 0 %}
<a class="active" href="/article/{{ kwargs.article_type_id }}-0.html">全部</a>
{% else %}
<a href="/article/{{ kwargs.article_type_id }}-0.html">全部</a>
{% endif %} {% for row in category %}
{% if row.id == kwargs.category_id %}
<a class="active" href="/article/{{ kwargs.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
{% else %}
<a href="/article/{{ kwargs.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
{% endif %}
{% endfor %}
</div> <h2>查询结果</h2>
<ul>
{% for row in articles %}
<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type }}]-[{{ row.category.caption }}]</li>
{% endfor %}
</ul>
</body>
</html>
article.html
from django.shortcuts import render
from django.shortcuts import HttpResponse # Create your views here. def index(request): return HttpResponse('Ok') from . import models
def article(request,*args,**kwargs): search_dict = {}
for key,value in kwargs.items():
kwargs[key] = int(value) # 把字符类型转化为int类型 方便前端做if a == b 这样的比较
if value !='':
search_dict[key] = value
print(kwargs)
articles = models.Article.objects.filter(**search_dict) # 字典为空时表示搜索所有 article_type = models.Article.type_choice print(article_type)
category = models.Categoery.objects.all() return render(request,'article.html',{'articles':articles,
'article_type':article_type,
'category':category ,
'kwargs':kwargs})
处理文件.py
数据库文件:
from django.db import models
# Create your models here.
class Categoery(models.Model):
caption = models.CharField(max_length=16) # class ArticleType(models.Model):
# caption = models.CharField(max_length=16) class Article(models.Model):
title = models.CharField(max_length=32)
content = models.CharField(max_length=255) category = models.ForeignKey(Categoery)
# article_type = models.ForeignKey(ArticleType)
type_choice = [
(1,'Python'),
(2,'Linux'),
(3,'大数据'),
(4,'架构'),
]
article_type_id = models.IntegerField(choices=type_choice)
3、利用simple_tag把代码优化
关联文件:
from django.db import models
# Create your models here.
class Categoery(models.Model):
caption = models.CharField(max_length=16) class ArticleType(models.Model):
caption = models.CharField(max_length=16) class Article(models.Model):
title = models.CharField(max_length=32)
content = models.CharField(max_length=255) category = models.ForeignKey(Categoery)
article_type = models.ForeignKey(ArticleType)
# type_choice = [
# (1,'Python'),
# (2,'Linux'),
# (3,'大数据'),
# (4,'架构'),
# ]
# article_type_id = models.IntegerField(choices=type_choice)
数据库文件.py
from django.shortcuts import render
from django.shortcuts import HttpResponse # Create your views here. def index(request): return HttpResponse('Ok') from . import models
def article(request, *args, **kwargs):
search_dict = {}
for key, value in kwargs.items():
kwargs[key] = int(value) # 把字符类型转化为int类型 方便前端做if a == b 这样的比较
if value != '':
search_dict[key] = value
articles = models.Article.objects.filter(**search_dict) # 字典为空时表示搜索所有 article_type = models.ArticleType.objects.all() print(article_type)
category = models.Categoery.objects.all() return render(request, 'article.html', {'articles': articles,
'article_type': article_type,
'category': category,
'kwargs': kwargs})
处理文件.py
{% load filter %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.condition a{
display:inline-block;
padding: 3px 5px;
border: 1px solid black;
}
.condition a.active{
background-color: brown;
}
</style>
</head>
<body>
<h2>过滤条件</h2>
<div class="condition">
{% filter_all kwargs 'article_type'%} {% filter_single article_type kwargs 'article_type'%}
</div>
<div class="condition">
{% filter_all kwargs 'category'%}
{% filter_single category kwargs 'category'%}
</div> <h2>查询结果</h2>
<ul>
{% for row in articles %}
<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type.caption }}]-[{{ row.category.caption }}]</li>
{% endfor %}
</ul>
</body>
</html>
article.html
创建templatetags目录,在目录下创建filter.py文件:
from django import template
from django.utils.safestring import mark_safe
register = template.Library() @register.simple_tag
def filter_all(kwargs,type_str):
print(type_str)
if type_str == 'article_type':
if kwargs['article_type'] == 0:
tmp = '<a href = "/article/0-%s.html" class ="active" > 全部 </a>'%(kwargs['category'])
else:
tmp = '<a href = "/article/0-%s.html"> 全部 </a>'%(kwargs['category']) elif type_str == 'category':
if kwargs['category'] == 0:
tmp = '<a href = "/article/%s-0.html" class ="active" > 全部 </a>' % (kwargs['article_type'])
else:
tmp = '<a href = "/article/%s-0.html"> 全部 </a>' % (kwargs['article_type']) return mark_safe(tmp) @register.simple_tag()
def filter_single(type_obj,kwargs,type_str): print(type_str)
tmp = ''
if type_str == 'article_type':
for row in type_obj:
if row.id == kwargs['article_type']:
tag = '<a class="active" href="/article/%s-%s.html">%s</a>\n'%(row.id,kwargs['category'],row.caption)
else:
tag = '<a href="/article/%s-%s.html">%s</a>\n' % (row.id, kwargs['category'],row.caption)
tmp +=tag
elif type_str == 'category':
for row in type_obj:
if row.id == kwargs['category']:
tag = '<a class="active" href="/article/%s-%s.html">%s</a>\n' % (kwargs['article_type'],row.id, row.caption)
else:
tag = '<a href="/article/%s-%s.html">%s</a>\n' % (kwargs['article_type'], row.id, row.caption)
tmp += tag return mark_safe(tmp)
HTML文件主体内容:
{% load filter %}
<body>
<h2>过滤条件</h2>
<div class="condition">
{% filter_all kwargs 'article_type'%} {% filter_single article_type kwargs 'article_type'%}
</div>
<div class="condition">
{% filter_all kwargs 'category'%}
{% filter_single category kwargs 'category'%}
</div> <h2>查询结果</h2>
<ul>
{% for row in articles %}
<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type.caption }}]-[{{ row.category.caption }}]</li>
{% endfor %}
</ul>
</body>
JSONP
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
原理:
- - 创建script标签
- - src=远程地址
- - 返回的数据必须是js格式
- - 只能发GET请求
1、什么是同源策略?
处理文件:
import requests
def jsonp(request):
# 获取url信息
response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301')
response.encoding = 'utf-8' # 进行编码 return render(request,'jsonp.html',{'result':response.text}) # response.text 请求内容
HTML文件:
<body>
<h1>后台获取的结果</h1>
{{ result }}
<h1>js直接获取结果</h1>
<input type="button" value="获取数据" onclick="getContent();" />
<div id="container"></div>
<script src="/static/jquery-1.8.2.js"></script>
<script>
function getContent() {
var xhr = new XMLHttpRequest(); // 创建对象
xhr.open('GET', 'http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301'); // GET方式打开
xhr.onreadystatechange = function () { // 收到返回值时执行
console.log(xhr.responseText);
};
xhr.send() // 发送
}
</script>
</body>
注:点击js直接获取结果时,浏览器显示下面报错信息,由于浏览器只接受http://127.0.0.1:8000发过来的信息,对于天气网站发过来的信息直接屏蔽掉了,这就是同源策略,那有没有什么方式可以解决?
XMLHttpRequest cannot load http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
2、巧用script标签src属性
script标签不受同源策略的影响
处理文件:
import requests
def jsonp(request):
# 获取url信息
response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301')
response.encoding = 'utf-8' # 进行编码 return render(request,'jsonp.html',{'result':response.text}) # response.text 请求内容 def jsonp_api(request):
return HttpResponse('alert(123)')
HTML文件:
<body>
<h1>后台获取的结果</h1>
{{ result }}
<h1>js直接获取结果</h1>
<input type="button" value="获取数据" onclick="getContent();" />
<div id="container"></div>
<script>
function getContent() {
var tag = document.createElement('script');
tag.src = '/jsonp_api.html';
document.head.appendChild(tag);
// document.head.removeChild(tag);
}
</script>
</body>
注:js请求时为了方便,还是请求的是当前程序url;执行完上面代码会发现一个神奇的状况,页面会弹出123信息,表明script获取信息成功
3、对前后端稍加改造,使用方法更加动态化
处理文件:
def jsonp(request): return render(request,'jsonp.html') # response.text 请求内容 def jsonp_api(request):
func = request.GET.get('callback') # 获取用户callback参数
content = '%s(10000)'%func # 执行func(10000)函数 return HttpResponse(content)
HTML文件:
<body>
<h1>后台获取的结果</h1>
{{ result }}
<h1>js直接获取结果</h1>
<input type="button" value="获取数据" onclick="getContent();" />
<div id="container"></div>
<script>
function getContent() {
var tag = document.createElement('script');
tag.src = '/jsonp_api.html?callback=list'; // 自定义callback参数,与后台达成默契
document.head.appendChild(tag);
// document.head.removeChild(tag);
}
function list(arg){ // 自定义函数与callback=list相对应
alert(arg);
}
</script>
</body>
注:js发请求时,带上callback参数,然后定义参数对应的方法,后台会把数据传入此方法内并且执行执行;至于要打印还是弹框,就看用户自己的需求去处理了;jsonp的原理和实现过程就是上述代码的实现
4、实例应用+ajax
处理文件:
import requests
def jsonp(request):
response = requests.get('http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403')
response.encoding = 'utf-8' # 进行编码 return render(request, 'jsonp.html', {'result': response.text}) # response.text 请求内容
HTML文件:
<body>
<h1>后台获取的结果</h1>
{{ result }}
<h1>js直接获取结果</h1>
<input type="button" value="获取数据" onclick="getContent();" />
<div id="container"></div>
<script src="/static/jquery-1.8.2.js"></script>
<script>
function getContent() {
$.ajax({
url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403',
type: 'POST',
dataType: 'jsonp', // 即使写的type是POST也是按照GET请求发送
jsonp: 'callback',
jsonpCallback: 'list'
});
} function list(arg){ // 自定义函数与callback=list相对应
console.log(arg);
var data = arg['data'];
for(k in data){
var tr = document.createElement('td');
var week = data[k]['week'];
var list = data[k]['list'];
tr.textContent =week
document.body.appendChild(tr);
console.log(week);
for(i in list){
var name = list[i]['name'];
console.log(name)
}}}
</script>
</body>
list({data:[ { "week":"周日", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] }, { "week":"周一", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周二", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周三", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周四", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周五", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周六", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] }] });
网站获取到的数据
注:实现的过程跟第3自己写的代码一毛一样,也是创建个script然后再删除
XSS过滤
博客后台中的栗子,用户创建文章的内容时,是不允许让用户提交<script>alert(123)</script>这样的代码;普通编辑模式下,用户写入<script>代码块,不会有什么影响,因为后台会把<script>代码块当成字符串进行前端显示;但是,如果在html源码编辑下,是不能让<script>标签在前端进行显示的,这时就需要用到XSS过滤,把一些特殊标签进行过滤掉
1、简单的标签过滤
依赖模块BeautifulSoup
pip install beatifulsoup4 模块安装
html = '''
<p class="story">
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<div name='root'>Once upon a time there w</div>
</p>
<p>
<div>Once upon a time there w</div>
</p>
<script>alert()</script>
'''
html字符串内容
① 清空<script>标签、a标签的class属性:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'html.parser') # html.parser内部解析器 会把字符串转化成有结构的文档
tag = soup.find('script') # tag <script>alert(123)</script> 找到的标签
tag.hidden = True # <script>标签消失
tag.clear() # 清空标签内容 a = soup.find('a') # 删除a标签的class属性
del a.attrs['class'] # {'href': 'http://example.com/lacie', 'id': 'link2', 'class': ['sister']} content = soup.decode() # 把对象转化为字符串
print(content)
'''
<p class="story">
<a href="http://example.com/lacie" id="link2">Lacie</a> and
<div name="root">Once upon a time there w</div>
</p>
<p>
<div>Once upon a time there w</div>
</p>
'''
② 通过白名单进行操作:
from bs4 import BeautifulSoup
tags ={ # 设置白名单
'p':['class'],
'div':['id']
}
soup = BeautifulSoup(html,'html.parser') # html.parser内部解析器 会把字符串转化成有结构的文档
for tag in soup.find_all(): # tag.name 先找子子孙孙、然后再往下找
if tag.name in tags: # p a div p div script 一次循环的标签
for k in list(tag.attrs.keys()): # 不在白名单对应的属性进行删除
if k not in tags[tag.name]:
del tag.attrs[k]
else: # 不在白名单的标签删除
tag.hidden = True
tag.clear() content = soup.decode() # 把对象转化为字符串
print(content) '''
<p class="story">
and
<div>Once upon a time there w</div>
</p>
<p>
<div>Once upon a time there w</div>
</p>
'''
2、博客XSS过滤
XSSFilter文件:
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, 'html.parser')
# 遍历所有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.decode()
调用方式:
content = form.cleaned_data.pop('content') # 移出 content需要在表ArticleDetail上手动添加、关联Article
content = XSSFilter().process(content) # 对content进行数据过滤 过滤到script等标签
上面代码用到了面向对象的单例模式-》》http://www.cnblogs.com/lianzhilei/p/5838821.html
《第二十五章》
Python开发【Django】:组合搜索、JSONP、XSS过滤的更多相关文章
- stark组件开发之组合搜索实现思路
- 关键字搜索. 可以做到的效果是, 输入20. 后太通过 Q() 函数. 来实现. 搜索是一个大的问题点. - 要想实现组合搜索, 首先要 明确的一点是. 在我当前的页面上, 正在进行展示的是 ...
- stark组件开发之组合搜索基本显示
数据的获取,上一篇,已经有了!然后就是,如何进行展示的问题.到了展示这里,又有了新的问题, 因为从数据库,取得的数据. 分为 queryset 和 tuple 两种数据结构.tuple 中,只是字符串 ...
- stark组件开发之组合搜索页面效果和 URL
页面效果,只是样式.这个好解决!yield 的时候. 返回几个样式出去就好了! 并且前端写上一些样式的css {% if search_group_row_list %} <div class= ...
- stark组件开发之组合搜索高级显示和扩展
上一篇,我只是做了. 默认的显示. def __iter__(self): '''默认显示. 用户可以自定制''' if isinstance(self.queryset_or_tuple, list ...
- python(Django之组合搜索、JSONP、XSS过滤 )
一.组合搜索 二.jsonp 三.xss过滤 一.组合搜索 首先,我们在做一个门户网站的时候,前端肯定是要进行搜索的,但是如果搜索的类型比较多的话,怎么做才能一目了然的,这样就引出了组合搜索的这个案例 ...
- python运维开发(二十二)---JSONP、瀑布流、组合搜索、多级评论、tornado框架简介
内容目录: JSONP应用 瀑布流布局 组合搜索 多级评论 tornado框架简介 JSONP应用 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. ...
- python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))
昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...
- Django 项目补充知识(JSONP,前端瀑布流布局,组合搜索,多级评论)
一.JSONP 1浏览器同源策略 通过Ajax,如果在当前域名去访问其他域名时,浏览器会出现同源策略,从而阻止请求的返回 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一 ...
- jsonp、瀑布流布局、组合搜索、多级评论(评论树)、Tornado初识
1.JSONP原理剖析以及实现 1.1 同源策略限制 用django分别建立两个项目,jsonp01和jsonp02,然后再在这两个项目里分别建立一个app,比如名字叫jsonp1.jsonp2:js ...
随机推荐
- list模块
一. concat(Things) -> string() Types: Things = [Thing] Thing = atom() | integer() | float( ...
- 【Java面试题】38 Collection 和 Collections的区别
Collection是集合类的一个顶级接口,其直接继承接口有List与Set 而Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序.搜索以及线程安 ...
- 解决error: Your local changes to the following files would be overwritten by merge
在项目里我们一般都会把自己第一次提交的配置文件忽略本地跟踪 1 [Sun@webserver2 demo]$ git update-index --assume-unchanged <filen ...
- js openwindow
进入许多网站时,有弹出式小窗口,它们五花八门,使我们捉摸不透下面就来介绍用JS制作9种制作弹出小窗口: 1.最基本的弹出窗口代码 其实代码非常简单: < SCRI ...
- CentOS 6.5配置SSH免密码登录
centos 系统对权限的设置非常微妙,如果权限设置大了则ssh 拒绝,如果权限小了,则ssh 更是被拒绝(我曾经配置好久没有打通,就是因为权限过大的原因) 参考链接:http://www.linux ...
- Ubuntu 14.04 Server i386 安装 Oracle11g_11.2.0.3 RAC
文档地址:doc 文档地址:doc
- AssetBundle中Unload()方法的作用
AssetBundle.Unload(false)的作用: 官网的解释是这样的: When unloadAllLoadedObjects is false, compressed file data ...
- Docker 集群管理
docker systemd unit file [Unit] Description=Docker Application Container Engine Documentation=http:/ ...
- OpenCV学习:图像的载入和显示
一.使用IplImage结构读取并显示图像文件: 运行结果: 二.使用Mat类读取并显示图像文件: 使用 Mat 类,内存管理变得简单,不再像使用 IplImage 那样需要自己申请和释放内存,而且一 ...
- 改善C#程序的建议5:引用类型赋值为null与加速垃圾回收
http://www.cnblogs.com/luminji/archive/2011/04/07/2007205.html 在标准的Dispose模式中(见前一篇博客“C#中标准Dispose模式的 ...