一、关于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>
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') #返回一个页面没有意义,就是一堆的字符串,拿到了这个页面,你怎么处理,你要做什么事情,根本就没有意义
urlpatterns = [ ... url(r'^ajax_add/', views.ajax_add), url(r'^ajax_demo1/', views.ajax_demo1), ... ]
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>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1> 欢迎来到xxx官网 </h1> </body> </html>
url(r'^login/', views.login,name='login'), url(r'^home/', views.home,name='home'),
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')
二、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就可以这样加 })
------------------
------------------
-------------------