Django之Ajax

  1. ajax(特点:异步请求和局部刷新)

    版本一:利用ajax做到局部刷新页面向后端提交数据,前端接受后端返回的数据来选择跳转还是添加页面信息。
    views:
        from django.shortcuts import render,HttpResponse
    
        # Create your views here.
        def login(request):
            if request.method=='GET':
                return render(request,'login.html')
            else:
                user = request.POST.get('username')
                pwd = request.POST.get('password')
                print(user,pwd)
                if user == 'liu' and pwd == '123':
                    return HttpResponse('1')
                else:
                    return HttpResponse('0')
        def home(request):
            return render(request,'home.html')	
    

    urls:

    from app01 import views
        urlpatterns = [
            url(r'^admin/', admin.site.urls),
            url(r'^login/$',views.login,name='login'),
            url(r'^home/$',views.home,name='home'),
    

    login.html:

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    用户名:<input type="text" id="username" >
    密码:<input type="password" id="password" >
    <button id="btn">提交</button>
    <span></span>
    </body>
    <script src="{% static 'jquery.js' %}"></script>
    <script>
        $('#btn').click(function () {
            var user = $('#username').val();
            var pwd = $('#password').val();
            console.log(user,pwd);
            $.ajax({
                url:'{% url "login" %}',
                type:'post',
                data:{username:user,password:pwd},
                success:function (res) {
                    console.log(res,typeof res);
                    if(res==='1'){
                        location.href = '/home/'
                    }else{
                        $('span').text('用户名或密码错误')
                    }
                }
            })
        })
    </script>
    </html>
    

    home.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>day,day,up</h1>
    </body>
    </html>
    
  2. csrftoken

    2.1 原理:

    详述CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。攻击者通过HTTP请求江数据传送到服务器,从而盗取回话的cookie。盗取回话cookie之后,攻击者不仅可以获取用户的信息,还可以修改该cookie关联的账户信息。
    

    1570707900302

    所以解决csrf攻击的最直接的办法就是生成一个随机的csrftoken值,保存在用户的页面上,每次请求都带着这个值过来完成校验。
    

    https://blog.csdn.net/qq_42327755/article/details/80575565?tdsourcetag=s_pcqq_aiomsg

    2.2 例证:

    form表单通过csrf认证
    login.html
        <form action="" method="post">
            {% csrf_token %}
            用户名:<input type="text" name="username">
            密码:<input type="password" name="password">
            <input type="submit">
        </form>
    
    ajax通过csrf认证(三种方式)
    第一种:
        <body>
        {% csrf_token %}-----浏览器渲染加上一个隐藏的input标签
        用户名: <input type="text" id="username">
        密码: <input type="password" id ='password'>
        <button id="btn">提交</button>
        <span></span>
        </body>
        <script src="{% static 'js/jquery.js' %}"></script>
        <script>
            $('#btn').click(function () {
                var user = $('#username').val();
                var pwd = $('#password').val();
                var csrf = $('[name=csrfmiddlewaretoken]').val();---获取隐藏input标签里的value值
                $.ajax({
                    url: '{% url "login" %}',
                    type: 'post',
                    data: {username: user, password: pwd,csrfmiddlewaretoken:csrf},---将数据添加上传
                    success: function (res) {
                        if (res === '1') {
                            location.href = '/home/'
                        } else {
                            $('span').text('用户名或密码错误')
                        }
                    }
                })
            })
        </script>
    
    第二种:
    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {#from表单通过csrf#}
    {#<form action="" method="post">#}
    {#    {% csrf_token %}#}
    {#    用户名:<input type="text" name="username">#}
    {#    密码:<input type="password" name="password">#}
    {#    <input type="submit">#}
    {#</form>#}
    
    {#{% csrf_token %}#}
    用户名: <input type="text" id="username">
    密码: <input type="password" id ='password'>
    <button id="btn">提交</button>
    <span></span>
    </body>
    <script src="{% static 'js/jquery.js' %}"></script>
    <script>
        $('#btn').click(function () {
            var user = $('#username').val();
            var pwd = $('#password').val();
            {#var csrf = $('[name=csrfmiddlewaretoken]').val();#}
            var csrf = '{{ csrf_token }}';---{{变量}}浏览器直接将变量渲染成csrf_token值
            {#var csrf = $('')#}
            $.ajax({
                url: '{% url "login" %}',
                type: 'post',
                data: {username: user, password: pwd,csrfmiddlewaretoken:csrf},
                success: function (res) {
                    if (res === '1') {
                        location.href = '/home/'
                    } else {
                        $('span').text('用户名或密码错误')
                    }
                }
            })
        })
    
    </script>
    </html>
    
    第三种:
    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    用户名: <input type="text" id="username">
    密码: <input type="password" id ='password'>
    <button id="btn">提交</button>
    <span></span>
    </body>
    <script src="{% static 'js/jquery.js' %}"></script>
    <script src="{%  static 'js/jquery.cookie.js'%}"></script>
    <script>
        $('#btn').click(function () {
            var user = $('#username').val();
            var pwd = $('#password').val();
    
            $.ajax({
                url: '{% url "login" %}',
                type: 'post',
                data: {username: user, password: pwd},
                headers:{
                    "X-CSRFToken":$.cookie('csrftoken'),
                },----直接对cookie操作添加键值对即可
                success: function (res) {
                    if (res === '1') {
                        location.href = '/home/'
                    } else {
                        $('span').text('用户名或密码错误')
                    }
                }
            })
        })
    </script>
    </html>
    
    1. 上传文件

      3.1 form表单上传文件

      views:
      from django.shortcuts import render,HttpResponse,redirect
      from django.http import JsonResponse
      def upload(request):
          if request.method=='GET':
              return render(request,'upload.html')
          else:
              print(request.POST)
              print(request.FILES)
              file_obj = request.FILES.get('file')
              print(file_obj.name)
              with open(file_obj.name,'wb') as f:
                 第一种: for i in file_obj:
                      f.write(i)
                 第二种:for chunk in file_obj.chunks():防止/r/n
                      f.write(chunk)
      
              return HttpResponse('ok')
              
         upload.html
         {% load static %}
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      <form action="" method="post" enctype="multipart/form-data">
          {% csrf_token %}
          用户名:<input type="text" id="username">
          密码:<input type="password" id = 'password'>
          <span></span>
          头像:<input type="file" name="file">
          <input type="submit">
      </form>
      </body>
      <script src="{% static 'js/jquery.js' %}"></script>
      </html>
      
      

      3.2 ajax上传文件

      views:
      from django.conf import settings
      def upload(request):
          if request.method=='GET':
              return render(request,'upload.html')
          else:
      
              file_obj = request.FILES.get('file')
              with open(file_obj.name,'wb') as f:
                  for chunk in file_obj.chunks():
                      f.write(chunk)
      
              return HttpResponse('ok')
      
      
      upload.html
      {% load static %}
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
          用户名:<input type="text" id="username">
          密码:<input type="password" id = 'password'>
          头像:<input type="file">
          <button id="stn">提交</button>
      </body>
      <script src="{% static 'js/jquery.js' %}"></script>
      <script src="{% static 'js/jquery.cookie.js' %}"></script>
      <script>
          $('#stn').click(function () {
              var formdata = new FormData();
              var user = $('#username').val();
              var pwd = $('#password').val();
              var file_obj = $('[type=file]')[0].files[0];
              formdata.append('user',user);
              formdata.append('pwd',pwd);
              formdata.append('file',file_obj);
              $.ajax({
                  url:'{% url "upload" %}',
                  type:'post',
                  data:formdata,
                  headers:{
                      "X-CSRFToken":$.cookie('csrftoken'),
                  },
                  processData:false,
                  contentType:false,
                  success:function (res) {
                      console.log(res)                      
                  }                     
              })
          }) 
      </script>
          
      </html>
      
      
    2. jsonresponse

      from django.http import JsonResponse
      
              username = request.POST.get('username')
              pwd = request.POST.get('password')
              ret_data = {'status':None,'msg':None}
              print('>>>>>',request.POST)
              #<QueryDict: {'{"username":"123","password":"123"}': ['']}>
              if username == 'chao' and pwd == '123':
                  ret_data['status'] = 1000  # 状态码
                  ret_data['msg'] = '登录成功'
              else:
                  ret_data['status'] = 1001  # 状态码
                  ret_data['msg'] = '登录失败'
      
              # ret_data_json = json.dumps(ret_data,ensure_ascii=False)
              # return HttpResponse(ret_data_json,content_type='application/json')
              return JsonResponse(ret_data)---做了上面两句话所做的事情
      
      
       $.ajax({
                  url:'{% url "jsontest" %}',
                  type:'post',
                  // data:{username:uname,password:pwd,csrfmiddlewaretoken:csrf},           //data:JSON.stringify({username:uname,password:pwd}),
                  data:{username:uname,password:pwd},
                  headers:{
                      // contentType:'application/json',
                      "X-CSRFToken":$.cookie('csrftoken'),
                  },
                  success:function (res) {
                      {#console.log(res,typeof res); // statusmsg {"status": 1001, "msg": "登录失败"}#}
                      {#var res = JSON.parse(res);  //-- json.loads()#}
                      console.log(res,typeof res);  //直接就是反序列化之后的了
                      //JSON.stringify()  -- json.dumps
                      if (res.status === 1000){
                          // $('.error').text('登录成功');
                          location.href = '/home/'; // http://127.0.0.1:8000/home/
                      }else{
                          $('.error').text(res.msg);
                      }
                  }
              })
      
      
原文地址:https://www.cnblogs.com/-777/p/11656502.html