码迷,mamicode.com
首页 > Web开发 > 详细

Django之Ajax

时间:2019-10-28 23:57:37      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:就是   cookies   cut   服务   import   lang   har   局部刷新   use   

1.Ajax简介

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

特点:

异步请求,局部刷新

2.局部刷新

如果是from表单提交之后,如果验证失败会自动刷新页面

使用Ajax能保证只刷新局部

示例:

url

from  app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login,name='login'),
    path('home/', views.home,name='home'),
]

views

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.


def login(request):

    if request.method == 'GET':
        return render(request,'login.html')
    else:
        uname = request.POST.get('username')
        pwd = request.POST.get('password')

        if uname == 'zbb' and pwd == '123':
            return HttpResponse('1')
        else:
            return HttpResponse('0')



def home(request):

    return render(request,'home.html')

login.html

<!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="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
        $('#sub').click(function () {

        var uname = $('#username').val();
        var pwd = $('#password').val();


        $.ajax({
            url:'{% url "login" %}',
            type:'post',
            data:{username:uname,password:pwd},
            success:function (res) {
                if (res === '1'){
                    location.href = '/home/';

                }else{
                    $('.error').text('用户名密码错误!');
                }

            }

        })

    })
</script>
</html>

home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登陆成功</h1>

</body>

</html>

3.CSRF

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

Django默认会禁止未标识 post请求

login.html

4.from请求设置

中加入 {% csrf_token %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    用户名: <input type="text" id="username">
    密码: <input type="password" id="password">
    <input type="submit">

</form>

<span class="error"></span>
</body>

</html>

5.Ajax请求设置

第一种方法

<!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="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
        $('#sub').click(function () {

        var uname = $('#username').val();
        var pwd = $('#password').val();
        var csrf = '{{ csrf_token }}'; //加在这里


        $.ajax({
            url:'{% url "login" %}',
            type:'post',
            data:{username:uname,password:pwd,csrfmiddlewaretoken:csrf},//发送出
            success:function (res) {
                if (res === '1'){
                    location.href = '/home/'; // http://127.0.0.1:8000/home/

                }else{
                    $('.error').text('用户名密码错误!');
                }

            }

        })

    })
</script>
</html>

第二种方法

需要引入一个jquery.cookie.js插件

<!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="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
<script>
        $('#sub').click(function () {

        var uname = $('#username').val();
        var pwd = $('#password').val();



        $.ajax({
            url:'{% url "login" %}',
            type:'post',
            data:{username:uname,password:pwd},
            headers:{
                "X-CSRFToken":$.cookie('csrftoken'), 
            },
 //其实在ajax里面还有一个参数是headers,自定制请求头,可以将csrf_token加在这里,我们发contenttype类型数据的时候,csrf_token就可以这样加           
            success:function (res) {
                if (res === '1'){

                    location.href = '/home/';

                }else{
                    $('.error').text('用户名密码错误!');
                }

            }

        })

    })
</script>
</html>

6.网络请求安全解决

常见的网络请求安全解决方法

Cookies Hashing:每一个表单请求中都加入随机的Cookie,由于网站中存在XSS漏洞而被偷窃的危险。 
HTTP refer:可以对服务器获得的请求来路进行欺骗以使得他们看起来合法,这种方法不能够有效防止攻击。 
验证码:用户提交的每一个表单中使用一个随机验证码,让用户在文本框中填写图片上的随机字符串,并且在提交表单后对其进行检测。 
令牌Token:一次性令牌在完成他们的工作后将被销毁,比较安全。

7.文件上传

请求头ContentType

    ContentType指的是请求体的编码类型,常见的类型共有3种:

1 application/x-www-form-urlencoded

  这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 默认格式application/x-www-form-urlencoded 方式提交数据,ajax默认也是这个。请求类似于下面这样(无关的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

user=yuan&age=22   #这就是上面这种contenttype规定的数据格式,后端对应这个格式来解析获取数据,不管是get方法还是post方法,都是这样拼接数据,大家公认的一种数据格式,但是如果你contenttype指定的是urlencoded类型,但是post请求体里面的数据是下面那种json的格式,那么就出错了,服务端没法解开数据。

2.multipart/form-data

这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data,form表单不支持发json类型的contenttype格式的数据,而ajax什么格式都可以发,也是ajax应用广泛的一个原因

3.application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

form表单文件上传

url

path('upload/', views.upload,name='upload'),

views

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)
        #文件太大只有一行怎么办?
            for chunk in file_obj.chunks():
        #默认一次返回大小为经测试为65536B,也就是64KB,最大为2.5M,是一个生成器
                f.write(chunk)


        return HttpResponse("ok")

upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
{#    告诉浏览器不要一起发送,要一段一段的发送,指定:ContentType ..指的是请求体的编码类型#}
     
    {% csrf_token %}
    用户名: <input type="text" name="username">
    密码: <input type="password" name="password">
    头像: <input type="file" name="file">
    <input type="submit">
    
</form>
</body>

</html>

Ajax文件上传

upload.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    用户名: <input type="text" name="username">
    密码: <input type="password" name="password">
    头像: <input type="file" name="file" multiple>
{#    multiple  的意思是可以上传多个#}
    <button id ='sub'>提交</button>
    <span class='error'></span>

</body>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/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,
            processData:false,
            contentType:false,
            //固定语法 不得对数据加工,直接发送原生数据
            headers:{
                "X-CSRFToken":$.cookie('csrftoken'),
            },
            success:function (res) {

                    $('.error').text('完成');


            }

        })

    })
</script>
</html>

8.json数据交互

技术图片

json数据类型和python数据类型的对比

技术图片

JsonResponse对象

    JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。

from django.http import JsonResponse

response = JsonResponse({'foo': 'bar'})
print(response.content)

b'{"foo": "bar"}'

class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None,**kwargs)

    这个类是HttpRespon的子类,它主要和父类的区别在于:

    1.它的默认Content-Type 被设置为: application/json

    2.第一个参数,data应该是一个字典类型,当 safe 这个参数被设置为:False ,那data可以填入任何能被转换为JSON格式的对象,比如list, tuple, set。 默认的safe 参数是 True. 如果你传入的data数据类型不是字典类型,那么它就会抛出 TypeError的异常。

    3.json_dumps_params参数是一个字典,它将调用json.dumps()方法并将字典中的参数传入给该方法。

#如果这样返回,ajax还需要进行json解析
#views.py
return HttpResponse(json.dumps({"msg":"ok!"}))

#index.html
var data=json.parse(data)
console.log(data.msg);

    使用HttpResponse对象来响应数据的时候,还可以通过content_type指定格式:

return HttpResponse(json.dumps(data),content_type="application/json")

    前端调试窗口就可以看到这个类型

    技术图片

    如果不写这个参数是这个类型:长得像json格式的字符串,当然也可以转换成json的

    技术图片

    看下面这种,JsonResponse默认就是content_type="application/json"。

#如果这样返回,两边都不需要进行json的序列化与反序列化,ajax接受的直接是一个对象
#views.py
from django.http import JsonResponse
return JsonResponse({"msg":"ok!"})

#index.html
console.log(data.msg);

urls

path('jsontest/', views.jsontest,name='jsontest'),

代码 views

from django.http import JsonResponse
import json
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 == 'zbb' 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')
         #ret_data = ['aa',22,'bb']  /如果是数组
            
        return JsonResponse(ret_data) #safe =Flaser

jsontest.html

<!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="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/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'),
            },
            success:function (res) {
                {#console.log(res,typeof res); // statusmsg {"status": 1001, "msg": "登录失败"}#}

                console.log(res,typeof res); //直接就是反序列化之后的了

                if (res.status === 1000){

                    location.href = '/home/';

                }else{
                    $('.error').text(res.msg);
                }

            }

        })

    })



</script>

</html>

9.补充一个SweetAlert插件

下载地址 百度jq2

https://github.com/lipis/bootstrap-sweetalert

url

path('chajian/', views.chajian)

views

def chajian(request):
    return render(request,'chajian.html')

html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap-theme.min.css' %}">
    <link rel="stylesheet" href="{% static 'bootstrap-sweetalert-master/dist/sweetalert.css' %}">
</head>
<body>

<div>
    <button class="btn btn-danger">删除</button>
</div>

</body>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>

<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'bootstrap-sweetalert-master/dist/sweetalert.js' %}"></script>
<script>

    $(".btn-danger").on("click", function () {
        swal({
                title: "你确定要删除吗?",
                text: "删除可就找不回来了哦!",
                type: "warning",
                showCancelButton: true,
                confirmButtonClass: "btn-danger",
                confirmButtonText: "我已经下定决心",
                cancelButtonText: "容我三思",
                closeOnConfirm: false
            },
            function () {
                var deleteId = $(this).parent().parent().attr("data_id");
                $.ajax({
                    url: "/delete_book/",
                    type: "post",
                    data: {"id": deleteId},
                    success: function (data) {
                        console.log(data,typeof data);
                        if (data === '1') {
                            swal("删除成功!", "你可以准备跑路了!", "success");
                        } else {
                            swal("删除失败", "你可以再尝试一下!", "error")
                        }
                    }
                })
            });
    })
</script>
</html>

Django之Ajax

标签:就是   cookies   cut   服务   import   lang   har   局部刷新   use   

原文地址:https://www.cnblogs.com/zdqc/p/11756110.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!