Django框架09 /ajax、crsf、settings导入

Django框架09 /ajax、crsf、settings导入

1. ajax概述

  • 使用Javascript语言与服务器进行异步交互,AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
  • 在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
  • 特性:异步请求/ 局部刷新

2. ajax应用

  • 代码示例:

    login.html

    {% load static %}  <!-- 引入jquery文件的第二种方式 -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <!-- form方式提交数据 -->
    <form action="" method="post">
        {% csrf_token %}
        用户名: <input type="text" name="username">
        密码: <input type="password" name="password">
        <input type="submit">
    </form>
    
    <!-- ajax方式提交数据 -->
    {% csrf_token %}
    用户名: <input type="text" id="username">
    密码: <input type="password" id="password">
    <button id="sub">提交</button>
    <span class="error"></span>
    
    </body>
    
    <!-- 原jquery文件引入方式 -->
    <script src="/static/js/jquery.js"></script>
    <!-- 引入jquery文件的第二种方式 -->  
    <script src="{% static 'js/jquery.js' %}"></script>
        
    <!-- 引入jquery.cookie文件,通过jquer操作cookie --> 
    <script src="{% static 'js/jquery.cookie.js' %}"></script>
    
    <script>
        $('#sub').click(function () {
            var uname = $('#username').val();
            var pwd = $('#password').val();
            var csrf = '{{ csrf_token }}';
    		
            //不发送数据
             $.ajax({
            	url:'{% url "login" %}',
             	type:'get',
                success:function (res) {
                    console.log(res);
                }
            })
    
            //发送数据
            $.ajax({
                url: '{% url "login" %}',
                type: 'post',
                data: {username: uname, password: pwd},
                success: function (res) {
                    console.log(res);
                    if (res === '1') {
                        // $('.error').text('登录成功');
                        location.href = '/home/'; // http://127.0.0.1:8000/home/
                    } else {
                        $('.error').text('用户名密码错误!');
                    }
                }
            })
        })
    
    </script>
    </html>
    

    view.py

    def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        else:
            uname = request.POST.get('username')  # ajax中data设置的键
            pwd = request.POST.get('password')
            if uname == 'liu' and pwd == '123':
                return HttpResponse('1')
            else:
                return HttpResponse('0')
    
    def home(request):
        return render(request,'home.html')
    

3. ajax上传文件

  • 代码示例:

    upload.html

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>文件上传</h1>
    
    <!-- form表单上传 enctype="multipart/form-data" *** -->
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        用户名: <input type="text" name="username">
        密码: <input type="password" name="password">
        头像: <input type="file" name="file"> 
        <input type="submit">
    </form>
    
    <!-- ajax上传 -->   
    {% csrf_token %}
    
    用户名: <input type="text" id="username">
    密码: <input type="password" id="password">
    <!-- 上传多个文件 -->    
    上传文件: <input type="file" multiple>
    <!-- 上传单个文件 -->   
    上传文件: <input type="file">
    
    <button id="sub">提交</button>
    <span class="error"></span>
    </body>
    
    <script src="{% static 'js/jquery.js' %}"></script>
    <script src="{% static 'js/jquery.cookie.js' %}"></script>
    
    <script>
    
        $('#sub').click(function () {
    
            var formdata = new FormData();
    
            var uname = $('#username').val();
            var pwd = $('#password').val();
            var file_obj = $('[type=file]')[0].files[0];
    
            formdata.append('username', uname);
            formdata.append('password', pwd);
            formdata.append('file', file_obj);
    
            $.ajax({
                url: '{% url "upload" %}',
                type: 'post',
                data: formdata,
                
                //必须写/告诉ajax不对data数据进行任何的加工处理
                processData: false, //不处理数据
                contentType: false,	//不设置内容类型
                
                headers: {
                    "X-CSRFToken": $.cookie('csrftoken'),
                },
                success: function (res) {
                    console.log(res);
                    if (res === '1') {
                        $('.error').text('上传成功');
                    } else {
                        $('.error').text('上传错误!');
                    }
                }
            })
        })
        
    </script>
    </html>
    

    view.py

    def upload(request):
        if request.method == 'GET':
            return render(request,'upload.html')
        else:
            print(request.POST)
            print(request.FILES)
            uname = request.POST.get('username')
            pwd = request.POST.get('password')
    
            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)
                # 按固定字节将文件写入,一次65531个字节    
                for chunk in file_obj.chunks():
                    f.write(chunk)
    
            return HttpResponse('ok')
    

4. jsonresponse应用

  • 代码示例:

    jsontest.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="sub">提交</button>
    <span class="error"></span>
    
    </body>
    
    <script src="{% static 'js/jquery.js' %}"></script>
    <script src="{% static 'js/jquery.cookie.js' %}"></script>
    
    <script>
    
        $('#sub').click(function () {
            var uname = $('#username').val();
            var pwd = $('#password').val();
    
            $.ajax({
                url: '{% url "jsontest" %}',
                type: 'post',
                data: {username: uname, password: pwd},
                headers: {
                    "X-CSRFToken": $.cookie('csrftoken'),
                    // contentType:'application/json',
                    // 可以指定传输文件的类型,指定json后django无法解析
                },
                success: function (res) {
    			   //方式一:
                    var res = JSON.parse(res);  //-- 相当于python中json.loads()
                    console.log(res, typeof res);
                    
                    //将对象转换成字符串类型
                    //JSON.stringify()  -- 相当于python中json.dumps
                    
                    //方式二、三
                    if (res.status === 1000) {
                        location.href = '/home/'; // http://127.0.0.1:8000/home/
    
                    } else {
                        $('.error').text(res.msg);
                    }
                }
            })
        })
    
    </script>
    </html>
    

    view.py

    def jsontest(request):
        """
        状态码;
            1000 : 登录成功
            1001 : 登录失败
    
        :param request:
        :return:
        """
    
        if request.method == 'GET':
            return render(request,'jsontest.html')
        else:
            username = request.POST.get('username')
            pwd = request.POST.get('password')
            ret_data = {'status':None,'msg':None}
            print('>>>>>',request.POST)
            # 如果ajax传输指定的内容类型是json的话,django无法解析
            # <QueryDict: {'{"username":"123","password":"123"}': ['']}>
            if username == 'liu' 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)
         
            # 方式二:
        	  return HttpResponse(ret_data_json,content_type='application/json')
        
        	  # 方式三:/省略将字典转换成字符串和指定类型
        	  return JsonResponse(ret_data)
        
            # 注意:当传输的数据ret_data是非字典数据类型的话JsonResponse不会序列化
            return JsonResponse(ret_data,safe=False)
        
        
    # django没有json类型解释器
    
    # django对内容类型解析伪代码
    '''
    ret = username=123&password=123  -- content-type:...urlencoded
    if content-type == 'urlencoded':
        res_list = ret.split('&')
        for i in res_list:
            k = i.split('=')
            request.POST[k[0]] = k[1]
    elif content-type=='multipart/form-data':
        ...
        request.FILES
    
    elif content-type == 'application/json'
    
    '''
    
  • 注意:

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

5. csrftoken /跨站请求伪造

  • csrf简述

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

  • 解决csrf攻击

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

  • form表单过csrf认证

    <form action="" method="post">
        {% csrf_token %}  
        <!-- form表单里面加上这个标签,模板渲染之后就是一个input标签 -->
        type=hidden  name=csrfmiddlewaretoken  value='asdfasdfasdf'
        用户名: <input type="text" name="username">
        密码: <input type="password" name="password">
        <input type="submit">
    </form>
    
  • ajax过csrf认证

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    {% csrf_token %}
    
    用户名: <input type="text" id="username">
    密码: <input type="password" id="password">
    <button id="sub">提交</button>
    <span class="error"></span>
    </body>
        
    
    <script src="{% static 'js/jquery.js' %}"></script>
    //引入jquery.cookie.js文件通过jqery操作cookie
    <script src="{% static 'js/jquery.cookie.js' %}"></script>
    
    <script>
        $('#sub').click(function () {
    
            var uname = $('#username').val();
            var pwd = $('#password').val();
    	    //方式一:
            var csrf = $('[name=csrfmiddlewaretoken]').val();
            //方式二:
            var csrf = '{{ csrf_token }}';
    
    
            $.ajax({
               url: '{% url "login" %}',
               type: 'post',
               //方式一、二:
               data:{username:uname,password:pwd,csrfmiddlewaretoken:csrf},
                
               //方式三: 
               data: {username: uname, password: pwd},
               headers: {
                    "X-CSRFToken": $.cookie('csrftoken'),
                },
                //其实在ajax里面还有一个参数是headers,自定制请求头,可以将csrf_token加在这里,我们发contenttype类型数据的时候,csrf_token就可以这样加
               success: function (res) {
                    console.log(res);
                    if (res === '1') {
                        location.href = '/home/'; 
                    } else {
                        $('.error').text('用户名密码错误!');
                    }
                }
            })
        })
    
    </script>
    </html>
    

6. django中setting引用

  • 方式一:

    from 项目名  import settings
    # 只能从项目目录下的setting去查找,找不到会报错,没有此setting项目也能启动
    
  • 方式二:

    from django.conf import settings  #推荐使用
    # 先从本项目目录下的setting查找,找不到去global setting去查找
    
    print(settings.BASE_DIR)  #/static/
    
原文地址:https://www.cnblogs.com/liubing8/p/11651172.html