欢迎来到 Kong Xiangqun 的博客

07.django之Ajax

一、关于Ajax

# AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”
# 即使用Javascript语言与服务器进行异步交互,传输的数据为XML
# 传输的数据不只是XML,现在更多使用json数据
"""
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
    a.同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    b.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
"""

1、Ajax示例

页面输入两个整数,通过AJAX传输到后端计算出结果并返回。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AJAX局部刷新实例</title>
</head>
<body>

<input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1">

<script src="/static/jquery-3.2.1.min.js"></script>
<script>
  $("#b1").on("click", function () {
    $.ajax({
      url:"/ajax_add/", //别忘了加双引号
      type:"GET",  
      data:{"i1":$("#i1").val(),"i2":$("#i2").val()}, //object类型,键值形式的,可以不给键加引号
      success:function (data) {
        $("#i3").val(data);
      }
    })
  })
</script>
</body>
</html>
ajax_demo1.html
def ajax_demo1(request):
    return render(request, "ajax_demo1.html")


def ajax_add(request):    #time.sleep(10)  #不影响页面发送其他的请求
    i1 = int(request.GET.get("i1"))
    i2 = int(request.GET.get("i2"))
    ret = i1 + i2
    return JsonResponse(ret, safe=False)    #return render(request,'index.html')  #返回一个页面没有意义,就是一堆的字符串,拿到了这个页面,你怎么处理,你要做什么事情,根本就没有意义
views.py
urlpatterns = [
    ...
    url(r'^ajax_add/', views.ajax_add),
    url(r'^ajax_demo1/', views.ajax_demo1),
    ...   
]
urls.py

2、Ajax应用场景

"""
1.注册时用户名查重
(当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,
然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。)
    整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
    当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,
服务器会查询名为kkkkk的用户是否存在,最终服务器返回true表示名为kkkkk的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”
2.搜索引擎用户输入关键字,自动提示检索关键字
"""

3、Ajax的优缺点

"""
1.AJAX使用JavaScript技术向服务器发送异步请求;

2.AJAX请求无须刷新整个页面;

3.因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;
"""

4、示例2:

写一个登陆认证页面,登陆失败不刷新页面,提示用户登陆失败,登陆成功自动跳转到网站首页。

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div>
    用户名:<input type="text" id="username">
    密码:<input type="text" id="pwd">
    {% csrf_token %}
    <button id="sub">提交</button>
    <span style="color: red;font-size: 12px;" id="error"></span>
</div>

<script src="{% static 'jquery.js' %}"></script>

<script>
    $('#sub').click(function () {
        $.ajax({
            url:"{% url 'login' %}",
            type:'post',
            data:{username:$('#username').val(),pwd:$('#pwd').val(),csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val()},

            success:function (data) {
                data = JSON.parse(data);
                console.log(data,typeof data);
                if (data['status']){

                    location.href=data['home_url'];
                }
                else {
                    $('#error').text('用户名或者密码错误!')
                }
            }

        })


    })



</script>

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

<h1>
    欢迎来到xxx官网
</h1>
</body>
</html>
base.html
url(r'^login/', views.login,name='login'),
url(r'^home/', views.home,name='home'),
urls.py
def login(request):
    res_dict = {'status':None,'home_url':None}
    if request.method == 'GET':
        return render(request,'login.html')
    else:
        uname = request.POST.get('username')
        pwd = request.POST.get('pwd')

        user_obj = models.UserInfo.objects.filter(name=uname,password=pwd).exists()
        import json
        if user_obj:

            res_dict['status'] = True
            res_dict['home_url'] = reverse('home')
            res_json_dict = json.dumps(res_dict)

            return HttpResponse(res_json_dict) #直接回复字典格式是不可以的,必须转换成json字符串,转换成普通字符串也是不行的,因为前端需要对json进行反序列获得这个字典,在通过字典的形式来操作数据。
        else:
            res_dict['status'] = False
            res_json_dict = json.dumps(res_dict)
            return HttpResponse(res_json_dict)
      # 如果你就是不使用JsonResponse的话,也可以给HttpResponse添加一个参数,content_type='application/json',那么前端ajax拿到数据之后,也是不需要反序列化的,ajax的回调函数就收到的就是一个反序列化之后的一个对象,因为ajax接受到数据后,通过这个data_type或者content_type发现你发送来的是个json格式的数据,那么ajax内容就自动将这个数据反序列化得到了js的数据对象,然后通过对象可以直接操作数据。      # return HttpResponse(res_json_dict,data_type='application/json')      # return JsonResponse(res_dict)
def home(request):

    return render(request,'base.html')
views.py

二、Ajax详解

1、基于jQuery的实现

<button class="send_Ajax">send_Ajax</button>
<script>

       $(".send_Ajax").click(function(){

           $.ajax({
               url:"/handle_Ajax/",
               type:"POST",
               data:{username:"chao",password:123},
               success:function(data){
                   //接收的是请求成功获取到的相应结果
                   console.log(data)
               },
               
               error: function (jqXHR, textStatus, err) {
                        //接收的是请求失败获取到的相应结果,根据响应码相应什么样的信息
                        console.log(arguments);
                    },

               complete: function (jqXHR, textStatus) {
               //与 ajaxSuccess() 不同,通过 ajaxComplete() 方法规定的函数会在请求完成时运行,即使请求并未成功。
                        console.log(textStatus);
                },

               statusCode: {
                    '403': function (jqXHR, textStatus, err) {
                          console.log(arguments);
                     },

                    '400': function (jqXHR, textStatus, err) {
                        console.log(arguments);
                    }
                }

           })

       })

</script>   

2、基于原生js实现

var b2 = document.getElementById("b2");
  b2.onclick = function () {
    // 原生JS
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("POST", "/ajax_test/", true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlHttp.send("username=chao&password=123456");
    xmlHttp.onreadystatechange = function () {
      if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
        alert(xmlHttp.responseText);
      }
    };
  };

3、ajax参数

3.1、data

"""
data:
当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式
(urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。
""" 
          function testData() {
               $.ajax("/test",{     //此时的data是一个json形式的对象
                  data:{
                    a:1,
                    b:2
                  }
               }); 
processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
             那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
             ,最后得到一个[object,Object]形式的结果。

3.2、contentType

"""
默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,
比如contentType:"application/json",即向服务器发送一个json字符串
"""
            $.ajax("/ajax_get",{
             
                  data:JSON.stringify({
                       a:22,
                       b:33
                   }),
                   contentType:"application/json",
                   type:"POST",
             
               });                          //{a: 22, b: 33}

             注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象

             views.py:   json.loads(request.body.decode("utf8"))

3.3、traditional

# 一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
# traditional为false会对数据进行深层次迭代;

3.4、服务器相应参数

"""
预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;
比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容
进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式
的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用data Type
dataType的可用值:html|xml|json|text|script
"""

三、Ajax请求设csrf_token

方式1:通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。

$.ajax({
  url: "/cookie_ajax/",
  type: "POST",
  data: {
    "username": "chao",
    "password": 123456,
    "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()  // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
  },
  success: function (data) {
    console.log(data);
  }
})

方式2:

$.ajaxSetup({
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

方式3:通过jquery

通过获取返回的cookie中的字符串 放置在请求头中发送。

注意:需要引入一个jquery.cookie.js插件。

<script src="{% static 'js/jquery.cookie.js' %}"></script>

$.ajax({
 
headers:{"X-CSRFToken":$.cookie('csrftoken')}, #其实在ajax里面还有一个参数是headers,自定制请求头,可以将csrf_token加在这里,我们发contenttype类型数据的时候,csrf_token就可以这样加
 
})

 

 

 

------------------

------------------

-------------------

 

posted @ 2020-10-06 00:08  kongxiangqun20220317  阅读(160)  评论(0编辑  收藏  举报