Skip to main content
 首页 » 编程设计

jquery之如何使用 Django + jQuery 修复 XSS

2025年05月04日27davidwang456

我编写了以下代码,这些代码用于Ajax 的消息功能。 当我填写

<script>alert("Django+Ajax");</script>  

在表单中提交,警报出现在我的浏览器上。 我想转义输出,但我不知道该怎么做。 你能给我一些建议吗?

消息.html

<html> 
<head> 
    <style type="text/css"> 
        div#message_form { 
            display: none; 
            margin: 25px; 
            padding: 25px; 
            background: #eee; 
            width: 200px; 
            height: 180px; 
        } 
    </style> 
</head> 
<body> 
 
    <input type="button" id="message" value="message">  <br /> 
    <div id="message_form"> 
        <form id="post_message" method="POST" action=""> 
            {% csrf_token %} 
            title: {{ form.title }}  <br /> 
            body: {{ form.body }}  <br /> 
            <input type="submit" value="send"> 
            <input type="reset" value="reset"> 
        </form> 
    </div>  
 
    <div id="get_title"></div> 
    <div id="get_body"></div> 
 
 
    {% load staticfiles %} 
    <script type="text/javascript" src="{% static "myapp/js/jQuery.js" %}"></script> 
    <script type="text/javascript" src="{% static "myapp/js/django_ajax.js" %}"></script> 
    <script type="text/javascript"> 
 
    $(function() { 
 
        $('#message').on('click', function() { 
            $('#message_form').slideToggle();    
        }); 
 
        $('#message_form').submit(function(e) { 
            e.preventDefault(); 
            var url = location.href; 
            var arr = url.split('/'); 
            $.ajax({ 
                type: 'POST', 
                url: '/myapp/deal_message/', 
                dataType: 'json', 
                data: { 
                    'title': $('#title').val(), 
                    'body': $('#body').val(), 
                    'target_id': arr[arr.length-2], 
                }, 
                success: function(data, dataType) { 
                    $('#get_title').append(data.title);  <!-- ### HERE ### --> 
                    $('#get_body').append(data.body);  <!-- ### HERE ### --> 
                    $('#post_message')[0].reset(); 
                }, 
                error: function(XMLHttpRequest, textStatus, errorThrown) { 
                    alert('Error: ' + errorThrown); 
                }, 
            }); 
            return false; 
        }); 
 
    }); 
 
    </script> 
</body> 
</html> 

表单.py

class Message(forms.ModelForm): 
 
    class Meta: 
        model = Message 
 
        fields = ('title', 'body',) 
        widgets = { 
            'title': forms.TextInput(attrs={'id': 'title', 'placeholder': 'message title'}), 
            'body': forms.Textarea(attrs={'rows': 4, 'cols': 18, 'id': 'body', 'placeholder': 'message body'}), 
        } 
        labels = {field:field for field in fields} 
        help_texts = {} 
        error_messages = {} 

View .py

#@login_required(login_url='/') 
def message(request, owner_id): 
    errors = "" 
 
    from myapp.forms import Message 
    view = {  
        'errors': errors, 
        'form': Message, 
    } 
    template = 'myapp/message/message.html' 
    return render(request, template, view) 
 
 
def deal_message(request): 
    u""" """ 
 
    #import pdb; pdb.set_trace() 
 
    errors = "" 
    sender_id = [request.user.user_id if isinstance(request.user.user_id, int) else 0].pop() 
    try: 
        target_id = int(request.POST['target_id']) 
    except ValueError as ve: 
        errors = ve 
 
 
    def chat_exist(sender_id, target_id): 
        # 1 on 1 
        from myapp.models import Chat 
        from myapp.models import Chat_Member 
 
        try: 
            sender_chats = Chat_Member.objects.filter(user_id=sender_id).filter(chat__type=0) 
            target_chats = Chat_Member.objects.filter(user_id=target_id).filter(chat__type=0) 
 
            cid = set([o.chat_id for o in sender_chats]) & set([o.chat_id for o in target_chats]) 
            if len(cid) == 0: 
                new_chat = Chat() 
                new_chat.type = 0 
                new_chat.save() 
 
                #new_chat.member = Chat_Member() 
                c1 = Chat_Member(chat_id=new_chat.chat_id, user_id=sender_id) 
                c2 = Chat_Member(chat_id=new_chat.chat_id, user_id=target_id) 
                c1.save() 
                c2.save() 
                return new_chat.chat_id 
            else: 
                if len(cid) != 1: 
                    raise 
                else: 
                    return cid.pop() 
        except: 
            return 0 
 
 
    chat_id = int(chat_exist(sender_id, target_id)) 
 
    res = {} 
 
    from myapp.forms import Message 
    formset = Message 
    if request.method == 'POST':     
        form = formset(request.POST) 
        if form.is_valid(): 
            try: 
                res['title'] = form.cleaned_data['title'] 
                res['body'] = form.cleaned_data['body'] 
                res = json.dumps(res) 
 
                from myapp.models import Chat 
                from myapp.models import Message 
 
                new_message = Message() 
                new_message.user_id = sender_id 
                new_message.chat_id = chat_id 
                new_message.title = form.cleaned_data['title'] 
                new_message.body = form.cleaned_data['body'] 
                new_message.save() 
 
                new_chat = Chat(chat_id=chat_id) 
                new_chat.last_message = form.cleaned_data['body'][:30] 
                new_chat.save() 
            except: 
                errors = "DB Error" 
        else: 
            errors = "" 
 
    return HttpResponse(res, content_type="application/json; charset=UTF-8") 

jQuery:2.2.0,Django:1.9.1,Python >: 3.5.1

请您参考如下方法:

您需要转义您在 JSON 对象中输出的 HTML。通常 Django 会在常规响应中为您完成该操作,但鉴于您将其封装在 JSON 中,它并不是那么简单。

使用escape 函数,如描述in this question ,在编码 JSON 之前,如下所示:

from django.utils.html import escape 
 
# ... 
 
res['title'] = escape(form.cleaned_data['title']) 
res['body'] = escape(form.cleaned_data['body']) 
res = json.dumps(res)