django – 之ajax请求

  • A+

一、说明

1.1、Ajax说明

  • AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

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

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

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

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;

  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

1.2、ajax的应用场景

搜索引擎根据用户输入的关键字,自动提示检索关键字。

还有一个很重要的应用场景就是注册时候的用户名的查重。

其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。

整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询用户是否存在,最终服务器返回true表示用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。

整个过程中页面没有刷新,只是局部刷新了;
在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;

1.3、Ajax的优缺点

优点:

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

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

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

缺点:

  • 频繁的请求可能会造成服务器端的压力。

二、ajax请求示例

1.urls.py内容

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^ajax_add/', views.ajax_add),
    url(r'^ajax_demo/', views.ajax_demo),
]

2.views.py内容

def ajax_demo(request):
    return render(request, "ajax_demo.html")

def ajax_add(request):
    i1 = int(request.GET.get("i1"))
    i2 = int(request.GET.get("i2"))
    ret = i1 + i2
    return JsonResponse(ret, safe=False)

3.ajax_demo.html内容

<!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>
  //给ID是b1的标签绑定点击事件触发匿名函数
  $("#b1").on("click", function () {
    // Ajax请求开始
    $.ajax({
      url:"/ajax_add/",      //请求的url地址
      type:"GET",      //请求的方法
      data:{"i1":$("#i1").val(),"i2":$("#i2").val()},     //往后端发送的数据,get请求时数据是可选的
      success:function (data) {     //回调函数,即服务器端回复我消息后,我干什么
        $("#i3").val(data);     //将id是i3的标签里设置内容为服务器端返回的数据
      }
    })
  })
</script>
</body>
</html>

说明:

  • data参数中的键值对,如果值不为字符串,需要将其转换成字符串类型。

三、Ajax请求时如何设置csrf_token

前面介绍了csrf_token是django内置的一个中间件,为了防止跨站请求伪造的,这里就介绍下ajax里使用csrf_token

3.1、方法一:通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。

//给id是b2的标签绑定点击事件
$("#b2").on("click", function () {
    var csrftoken = $("[name='csrfmiddlewaretoken']").val();     //获取csrf_token的键取值
  $.ajax({
    url:"/ajax_add3/",
    type:"POST",
    data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"csrfmiddlewaretoken":csrftoken},     //将csrf_token的值传给后端即可,后端自己做检验
    success:function (data) {
      $("#i3").val(data);
    }
  })
});

3.2、方法二:自己写一个获取Cookie的方法,将Cookie的值放到请求头里

  • 将getCookie方法和设置请求方法写在一个文件里,我这里给这个文件命名ajax_set-csrf-token.py,内容如下:
# getCookie的方法
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

#为ajax请求统一设置。
function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

说明:

  • 如果使用从cookie中取csrftoken的方式,需要确保cookie存在csrftoken值。

  • 如果你的视图渲染的HTML文件中没有包含 {% csrf_token %},Django可能不会设置CSRFtoken的cookie。

  • 这个时候需要使用ensure_csrf_cookie()装饰器强制设置Cookie。

  • 使用ajax_set-csrf-token.py这个文件

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

{% csrf_token %}
<input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交-GET" id="b1">
<input type="button" value="AJAX提交-POST" id="b2">
<input type="button" value="AJAX异步提交-IMG" id="b3">

<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/ajax_set-csrf-token.js"></script>    /*引用ajax_set-csrf-token.js文件*/
<script>

  //引用ajax_set-csrf-token.py文件后使用ajax请求就和平时请求的方式一样了
  $("#b2").on("click", function () {
    $.ajax({
      url:"/ajax_add3/",
      type:"POST",
      data:{"i1":$("#i1").val(),"i2":$("#i2").val()},
      success:function (data) {
        $("#i3").val(data);
      }
    })
  });

</script>
</body>
</html>

四、练习 - 判断用户名是否已注册

使用ajax练习判断用户输入的用户名是否已注册,如果注册就提示用户名已注册,如果未注册就什么也不提示。
1.HTML代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">        <!-- 加这个标签,bootstrap自动支持移动端的适配 -->
    <title>Ajax Test Package</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>

<p><input type="text" name="user" id="i1"></p>   <!-- 用户输入标签 -->

<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/ajax_set-csrf-token.js"></script>      //导入设置csrf_token文件

<script>
   //给id是i1标签绑定事件
    $("#i1").blur(function () {
        var $i1Ele = $(this);       //获取当前标签
        var name = $i1Ele.val();      //获取当前标签的值(输入的值)
        $i1Ele.next("span").remove();      //删除当前标签下的span标签
        $.ajax({     //ajax请求
            url:"/chack_name/",     //请求的url
            type:"post",      //请求方法
            data:{"name":name},     //将用户输入的值传给后端
            datatype:"json",     //传输的数据类型和接收的数据类型都是json类型
            success:function (arg) {    //回调函数
                var spanEle = document.createElement("span");     //创建span标签
                spanEle.innerText = JSON.parse(arg);     //服务器端返回的内容赋值给刚创建的span标签
                $(spanEle).css("color","red");     //设置span标签的颜色为红色
                //将span标签加到i1的后面
                $i1Ele.after(spanEle);

            }
        })

    })
</script>

</body>
</html>

2.后端代码

from django.shortcuts import render,HttpResponse
from app01 import models
import json

def chack_name(request):
    if request.method == "POST":
        name = request.POST.get("name")
        ret = models.UserInfo.objects.filter(name=name)
        if ret:
            #用户名已经存在
            msg = json.dumps("用户名已注册")
        else:
            msg = json.dumps("用户名可用")
        return HttpResponse(msg)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: