Ajax、contentType

​ 利用ajax与后端交互,取得后端反馈过来的数据进行处理,从而在浏览器在不刷新的情况下,进行局部更新异步请求

Ajax的用法一

{# 本示例,实现的是页面不刷新实现账号密码验证登入#}
<script>
    $('#myajax').click(function (){
        $.ajax({
            url:{% url 'mylogin' %},
            type:'POST',
            data: {
                uname: $('#username').val(),
                pwd: $('#password').val(),
                csrfmiddlewaretoken: '{{ csrf_token }}'
            },
            success:function (res){
      					{# 反序列化 #}
                var resStr = JSON.parse(res)
                if (resStr['status']==1)
                {
                    location.href=resStr['content']
                }
                else if(resStr['status']==2)
                {
                    $('#error').text(resStr['content'])
                }
            }
        })
    })
</script>
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        username = request.POST.get('uname')
        password = request.POST.get('pwd')

        if username == 'messi' and password == '123':
            res_content1 = {'status': 1, 'content': reverse('books')}
            return HttpResponse(json.dumps(res_content1))
        else:
            res_content2 = {'status': 2, 'content': '账户名或密码错误'}
            return HttpResponse(json.dumps(res_content2))

外部文件导入的方式来写js代码,那么js代码中不能写django的模板语法。因为html文件的加载顺序:url--视图--html模板渲染 --- return给浏览器 -- 浏览器渲染 --- srcipt的src --才去请求js文件 --那么这个js文件的代码此时才加载到你的html文件中 -- 就没有模板渲染的步骤了 -- 就没有办法替换对应的模板语法。(只能写死)

conten_type用法解析

​ 后端在返回数据的时候指定一个响应头content_type='application/json‘,那么ajax在拿到后端发过来的数据的时候,便无需我们手动进行反序列化,它看到content_type='application/json‘的时候,会自己反序列化好后再返回一个结果。

<script>
    $('#btn_login').click(function (){
        $.ajax({
            url:'{% url 'mylogin' %}',
            type:'POST',
            data: {
                uname: $('#name').val(),
                pwd: $('#inputPassword3').val(),
                csrfmiddlewaretoken: '{{ csrf_token }}'
            },
                          
            success:function (res){
                {#无需反序列化#}
                {#var resStr = JSON.parse(res)#}
                resStr = res
                console.log(res)
                if (resStr['status']==1)
                {
                    location.href=resStr['content']
                }
                else if(resStr['status']==2)
                {
                    $('#error').text(resStr['content'])
                }
            }

        })
    })
</script>
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        username = request.POST.get('uname')
        password = request.POST.get('pwd')

        if username == 'messi' and password == '123':
            res_content1 = {'status': 1, 'content': reverse('books')}
            return HttpResponse(json.dumps(res_content1), content_type='application/json')
        else:
            res_content2 = {'status': 2, 'content': '账户名或密码错误'}
            #再返回数据的时候加一个响应头content_type='application/json'
            return HttpResponse(json.dumps(res_content2), content_type='application/json')

JsonResponse是HttpResponse的子类,他帮我们做了两件事:1.序列化数据;2.添加content_type='application/json'的响应头

from django.http import JsonResponse
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        username = request.POST.get('uname')
        password = request.POST.get('pwd')

        if username == 'messi' and password == '123':
            res_content1 = {'status': 1, 'content': reverse('books')}
            # return HttpResponse(json.dumps(res_content1), content_type='application/json')
            return JsonResponse(res_content1)
        else:
            res_content2 = {'status': 2, 'content': '账户名或密码错误'}
            # return HttpResponse(json.dumps(res_content2), content_type='application/json')
            return JsonResponse(res_content2)

后端content_type默认=text/html,ajax默认的content_type=application/x-www-form-urlencoded; charset=UTF-8

解析器,就是根据Content_type来处理数据的。

  1. 当后端以content_type=text/html响应时,前端ajax,不能自动反序列化后端发过来的数据;
  2. 当后端以content_type=application/json响应时,前端ajax,自动反序列化后端发过来的数据;
  3. 当前端以content_type=application/x-www-form-urlencoded; charset=UTF-8请求时,后端Django能有一套解析前端发来数据的机制,所有我们能够使用request.POST.get['name']取得所对应的数据;
  4. 当前端以content_type=application/json请求时,后端Django没有一套解析前端发来数据的机制,所有我们能够使用request.body取得所byte类型对应的数据,然后自己处理,得到我们想要的数据(如示例所示)。
<script>
    var content = {};
    content.name = 'mkc';
    content.pwd = '123';
    content.csrfmiddlewaretoken='{{ csrf_token }}';
    console.log(content)
    var data = JSON.stringify(content)
    $.ajax({
        url:'{% url 'data' %}',
        type:'POST',
        data:data,
        contentType: 'application/json',
        success:function (res){
            $.each(res, function (k, v){
                str = '<li>' + v + '</li>'
                $('#o1').append(str)
             })
            console.log(res);
        }
     })
</script>
def data(request):
    res_data = ['红楼梦', '水浒传', '三国演义', '西游记']
    print(request.POST)  #<QueryDict: {}>
    print(request.body)  #b'{"name":"mkc","pwd":"123","csrfmiddlewaretoken":"PeqnHO8FTcGMAftGpXFm7D7nnJX7ti5OrNRtwCdHeSi1ZhkES76OMJR9TdY7R85c"}'
    recv_data = request.body.decode('utf-8')
    print(recv_data) #{"name":"mkc","pwd":"123","csrfmiddlewaretoken":"PeqnHO8FTcGMAftGpXFm7D7nnJX7ti5OrNRtwCdHeSi1ZhkES76OMJR9TdY7R85c"}
    recv_content = json.loads(recv_data)
    print(recv_content)
    name = recv_content['name']
    print(name)

Ajax的用法二

​ 对于后端发送的非字典数据,需要在后端设置safe=False,才能让ajax解析非字典数据

$.ajax({
    url:'{% url 'data' %}',
    type:'GET',
    success:function (res){
        console.log(res);
    }
})
def data(request):
    res_data = ['红楼梦', '水浒传', '三国演义', '西游记']
    return JsonResponse(res_data, safe=False)

ajax用法二:局部添加数据

<script>
    $.ajax({
        url:'{% url 'data' %}',
        type:'GET',
        success:function (res){
            $.each(res, function (k, v){
                str = '<li>' + v + '</li>'
                $('#o1').append(str)
             })
            {#console.log(res);#}
        }
    })
</script>
原文地址:https://www.cnblogs.com/messi-mu/p/14310716.html