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

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

1.ajax简介

1.AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。
2.AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

3.特性:
    异步请求
    局部刷新
    a.同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    b.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
    
1) AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
2) AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

2.ajax应用示例

1.login.html

{% load static %}  #引入jqery文件的第二种方式
<!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>

#原jqery文件引入方式
<script src="/static/js/jquery.js"></script>
    
#引入jqery文件的第二种方式    
<script src="{% static 'js/jquery.js' %}"></script>
#引入jqery.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.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',
                //可以指定传输文件的类型
            },
            success: function (res) {
               //方式一:
                var res = JSON.parse(res);  //-- json.loads()
                console.log(res, typeof res);
                
                //将对象转换成字符串类型
                //JSON.stringify()  -- 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)
        #<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)
     
        # 方式二:
    return HttpResponse(ret_data_json,content_type='application/json')
    
        # 方式三:/省略将字典转换成字符串和指定类型
        return JsonResponse(ret_data)
    
    
#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

5.1 简介

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

img

5.2 解决csrf攻击

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

5.3 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>

5.4 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/

猜你喜欢

转载自www.cnblogs.com/liubing8/p/11651172.html