1、django之博客-实现评论、XSS攻击防护,2、在kindedit中实现图片预览

评论实现:

最终要获取后端传来的评论结果:

<script>
    $.ajax({ 
     url:
'/content',
     type:"GET",
     dataType:'JSON',
     success:functaion(arg){
        if (arg){
          var comment=commentTree(arg.data);
          $('#commentArea').append(comment);
        }else{
          alter(arg.msg)
           }
        }
      
}); // 自定义方法format String.prototype.Format=function (arg) { /* console.log(this,arg)//this 就是asf(当前字符串), arg是参数(Format方法传入的参数 ) 例如有一个字符串是这样: this 就是 " i am {name} ,age {age} arg 就是 '{name} {age}' return 111; 格式化之后获取的新内容 */ var temp=this.replace(/\{(\w+)\}/g,function (k,kk) { /* k 匹配到的是 {asf},然后kk再对上一次进行匹配得到的是asf,然后arg字典返回了一个,=*/ return arg[kk]; }); return temp; }; v='{asf}'; v.Format; function commentTree(commentList) { /* * commentList 是上面通过ajax 从后端获取的评论结果, * * */ var comment_str="<div class='comment'>'"; $.each( commentList,function (k,row) { var temp="<div class='content'{content}</div>".Format({content:row.content}) comment_str+=temp; if (row.child.length()>0){ comment_str+=commentTree(row.child); } } ) }

附录:自定义字符串格式化详解:

 

XSS攻击防护:

BeautifulSoup 库,过滤掉script标签,与form表单配合使用

详细查看:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

xss.py :#封装在utils 下

from bs4 import BeautifulSoup
#BeautifulSoup 是一个可以从XML、HTML中提取数据的PYTHON库,帮助开发者节省时间 。
#https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

def xss(comment_content):

    # 白名单,没有恶意的script 标签
    valid_tag={
        'p':['class','id'],
        'img':['src'],
        'div':['class'],
        'title':['class'],
    }
    soup=BeautifulSoup(comment_content,'html.parser') #初始化一个BS对象,还有另一个方法,soup = BeautifulSoup(comment_content,'html.parser')

    tags=soup.find_all()#拿到当前所有的节点(也就是所有的标签),是一个HTML对象包着很多的标签对象。find_all()里可以指定参数
    # print(tags)
    for tag in tags:#进入到HTML对象里,拿到每一个标签对象
        if tag.name not in valid_tag: #tag.name 是标签名
            #print(tag.name)
            tag.decompose() #decompose方法将当前节点移除文档树并完全销毁:----就是干死了
        if tag.attrs:# 有 属性的标签
            for k in list(tag.attrs.keys()):#{'class': ['sister'], 'href': 'http://example.com/elsie', 'id': 'link1'}
                if k not in valid_tag[tag.name]:
                    del tag.attrs[k]

    content_str=soup.decode()#可以调用 encode() 方法获得字节码或调用 decode() 方法获得Unicode.
    return content_str



html_doc = """
    <head><title class='abc'>The Dormouse's story</title></head>
 
    <p class="abc" id='p1'><b>The Dormouse's story</b></p>
   
    <p class="story" id='2'>Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" 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">Tillie</a>;
    and they lived at the bottom of a well.</p>
    <script>alter(123)</script>
    <p class="story">...</p>
    
    """
xss(html_doc)

form.py

def CommentForm(Form):
    title=fields.CharField(max_length=128)
    content=fields.CharField(widget=widgets.Textarea(attrs={'id':'i1'}))
    def clean_content(self):
        user_content=self.cleaned_data['content']
        from utils.xss import xss#导入xss
        return xss(user_content)#将数据传给xss 过滤,有script 的将它过滤出来

 views.py 

from app01.forms import CommentForm
CONTENT=''
# 发布评论内容
def publish(request):
    if request.method=='GET':
        obj=CommentForm()
        return render(request,'publish.html',{'obj':obj})
    else:
        obj=CommentForm(request.POST)
        if obj.is_valid():
            print(obj.cleaned_data)
            content=obj.cleaned_data['content']

            global CONTENT
            CONTENT=content
            print(content)
            return HttpResponse('....')
def see(request): #查看上传文章 的结果
return render(request,'see.html',{'con':CONTENT})
###see.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ con|safe }}
</body>
</html>

 

 

前端publish.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/publish/" method="POST" novalidate>
    {% csrf_token %}
    <p>
    文章标题: {{ obj.title }}
    </p>
    <div>
        <div>文章内容</div>
        {{ obj.content }}
    </div>
    <!--<textarea name="content" id="i1" cols="30" rows="10">-->
     <!--</textarea>-->

    <input type="submit" value="submit">
</form>

<script src="/static/kindeditor-4.1.10/kindeditor-all.js"></script>//导入kindeditor,
<script>
KindEditor.create('#i1',{ width:'700px', height:'500px', // 控制显示的工具 items:[ 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage', 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', 'anchor', 'link', 'unlink', '|', 'about' ], // 显示出来的工具,但是不让用,显示灰色 // noDisableItems:['undo','redo'], // designMode:false, // 评论里面的上传文件--------这里是上传图片 uploadJson:'/upload_img',//对应的url,看《附录》 extraFileUploadParams:{ 'csrfmiddlewaretoken':'{{ csrf_token }}' } } ) </script> </body> </html>

 

测试: 

 

 

查看结果:script 没有发挥作用,拦截有效

 

《附录》

图片的上传:

前端上传代码:

    <form method="POST" action="/wangzhe.html" novalidate>
        {% csrf_token %}
        <p>
            文章标题
            {{ obj.title }}
        </p>

        <div>
            <div>文章内容</div>
            <div>
                {{ obj.content }}
            </div>
        </div>
        <input type="submit" value="提交" />
    </form>
    <script src="/static/kindeditor-4.1.10/kindeditor-all.js"></script>

    <script>
        KindEditor.create("#i1",{
            width: "700px",
            height: "300px",
            resizeType:1,
            uploadJson: '/upload_img.html',
            extraFileUploadParams:{
                "csrfmiddlewaretoken":"{{ csrf_token }}"
            }
        })
    </script>

views.py对应的处理函数 :

def upload_img(request):
    import os

    # 判断上传的类型文件
    upload_type=request.POST.get('dir')
    # 还需要再做下一步判断


    file_obj=request.FILES.get('imgFile')  #kindedit 的提交时,它的内部就是ifram + from 表单,伪AJAX的提交,而且这个文件只能叫imgFile----> 实际就是input type='file' name='imgIlf ,'要是改这个名字的话需要在前端添加filePostName:'fafa',那这里就要获取fafa了,参考:编辑器初始化参数http://kindeditor.net/docs/option.html
    file_path=os.path.join('static/img/',file_obj.name)
    with open(file_path,'wb') as f:
        for chunk in file_obj.chunks():
            f.write(chunk)

    #  返回的数据只能是这几个KEY,
    dic = {
        'error': 0,
        'url': '/'+file_path,#图像文件的路径,这样就能在前端预览了。
        'message': '错误了...'
    }

    import json
    return HttpResponse(json.dumps(dic))
    print(request.POST,request.FILES)

 

查看结果: 

 

在输入文章的框 中预览: 

 

 

 

 

附:

《自定义字符串方法》

1、

 

2、

3、前端的正则匹配

4、加上g,#glob 全部替换

5、有第二个参数 :,参数拿到的是匹配正则的

6、

再加个kk,拿到的就是没有大括号的

 

k={name}   等于的是加上括号的值 

kk=name   等于的是没有括号的值

 

 

 

 

 

 

 

posted @ 2017-07-19 16:40  tonycloud  阅读(591)  评论(0)    收藏  举报