Django-Ajax

知识预览

  • Ajax准备知识:Json

  • Ajax简介

  • JQuery实现的Ajax

  • JS实现的Ajax

  • jQuery.serialize()

  • 上传文件

  • 同源策略与Jsonp

Ajax准备知识:json

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。
它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

JS类型如何通过Json转换成python类型,如下图所示:

 

合格的json对象:

1 ["one", "two", "three"]
2 { "one": 1, "two": 2, "three": 3 }
3 {"names": ["张三", "李四"] }
4 [ { "name": "张三"}, {"name": "李四"} ] 

不合格的json对象:

1 { name: "张三", 'age': 32 }                     // 属性名必须使用双引号
2 [32, 64, 128, 0xFFF] // 不能使用十六进制值
3 { "name": "张三", "age": undefined }            // 不能使用undefined
4 { "name": "张三",
5   "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
6   "getName":  function() {return this.name;}    // 不能使用函数和日期对象
7 }  

strngify与parse方法

1 JSON.parse():     用于将一个 JSON 字符串转换为 JavaScript 对象 
2 eg:
3 console.log(JSON.parse('{"name":"Yuan"}'));
4 console.log(JSON.parse('{name:"Yuan"}')) ;   // 错误,name没有加引号
5 console.log(JSON.parse('[12,undefined]')) ;   // 错误,json内不能有默认值
6 JSON.stringify(): 用于将 JavaScript对象的值转换为 JSON 字符串。  7 eg: console.log(JSON.stringify({'name':"egon"})) ;

和XML的比较

JSON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁琐笨重的 XML 格式。

JSON 格式有两个显著的优点:书写简单,一目了然;符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。所以,JSON迅速被接受,已经成为各大网站交换数据的标准格式,并被写入ECMAScript 5,成为标准的一部分。

xml和json都使用结构化方法来标记数据,下面来做一个简单的比较:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <country>
 3     <name>中国</name>
 4     <province>
 5         <name>黑龙江</name>
 6         <cities>
 7             <city>哈尔滨</city>
 8             <city>大庆</city>
 9         </cities>
10     </province>
11     <province>
12         <name>广东</name>
13         <cities>
14             <city>广州</city>
15             <city>深圳</city>
16             <city>珠海</city>
17         </cities>
18     </province>
19     <province>
20         <name>台湾</name>
21         <cities>
22             <city>台北</city>
23             <city>高雄</city>
24         </cities>
25     </province>
26     <province>
27         <name>新疆</name>
28         <cities>
29             <city>乌鲁木齐</city>
30         </cities>
31     </province>
32 </country>
用XML表示中国部分省市数据
 1 {
 2     "name": "中国",
 3     "province": [{
 4         "name": "黑龙江",
 5         "cities": {
 6             "city": ["哈尔滨", "大庆"]
 7         }
 8     }, {
 9         "name": "广东",
10         "cities": {
11             "city": ["广州", "深圳", "珠海"]
12         }
13     }, {
14         "name": "台湾",
15         "cities": {
16             "city": ["台北", "高雄"]
17         }
18     }, {
19         "name": "新疆",
20         "cities": {
21             "city": ["乌鲁木齐"]
22         }
23     }]
24 }
用json表示

可以看到,JSON 简单的语法格式和清晰的层次结构明显要比 XML 容易阅读,并且在数据交换方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用得带宽。

注意:

JSON格式取代了xml给网络传输带来了很大的便利,但是却没有了xml的一目了然,尤其是json数据很长的时候,我们会陷入繁琐复杂的数据节点查找中。
但是国人的一款在线工具 BeJsonSoJson在线工具让众多程序员、新接触JSON格式的程序员更快的了解JSON的结构,更快的精确定位JSON格式错误。

 Ajax简介

 

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

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

AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

js实现的局部刷新

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <a href="/get_OK/">点击</a>&nbsp<span class="error"></span>
10 <hr>
11     <p>姓名 <input type="text"></p>
12     <p>密码 <input type="password"></p>
13 <p><button class="Ajax_send">Ajax_send</button><span class="login_error"></span></p>
14 
15 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
16 <script>
17    $(".Ajax_send").click(function(){               {# 给指定标签添加事件#}
18         {#ajax请求头的内容#}
19         $.ajax({
20             url:"/get_ajax/",   {#获取请求路径#}
21             type:"GET",          {#获取请求方式#}
22             data:JSON.stringify({
23                 name:$(":text").val(),
24                 pwd:$(":password").val()    {#获取用户输入的用户及密码#}
25             }),      {#请求数据,是一个js数据,打包时会ajax会组成 ?name=yuan&pwd=123#}
26 
27             contentype:"application/json",
28 
29             success:function (data) {
30                 var data=JSON.parse(data);
31                 console.log(data);      {#data接受后台发过来的数据#}
32 {#                $(".error").html(data);  {#将views的数据传入span标签的error内#}
33                 if(!data["flag"]){      {#条件不满足的情况下执行以下代码#}
34                     $(".login_error").html("用户名或者密码错误")
35                 }
36             }
37         })
38     })
39 </script>
40 </body>
41 </html>
View Code

Ajax常见的应用场景

1、当我们在百度中输入一个“老字后,会马上出现一个和老相关的热搜关键字(这里会涉及到SEO)下拉列表!

2、在各种网站注册,当你在用户名输入完毕,切换到密码框输入时,用户名处提醒:该用户已被使用。

其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,服务器将一个和数据库比对过后的结果返回给浏览器。

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

Ajax的优点

1、Ajax使用JavaScript技术向服务器发送异步请求;

2、Ajax无需刷新整个页面;

3、因为服务器响应内部不再是整个页面,而是页面中的局部,所以Ajax性能高。

jQuery实现的ajax

 1 {% load staticfiles %}
 2 
 3 <!DOCTYPE html>
 4 
 5 <html lang="en">
 6 <head>
 7     <meta charset="UTF-8">
 8     <title>Title</title>
 9     <script src="{% static 'JS/jquery-3.1.1.js' %}"></script>
10 </head>
11 <body>
12 
13 <button class="send_Ajax">send_Ajax</button>
14 
15 <script>
16       //$.ajax的两种使用方式:
17 
18       //$.ajax(settings);
19       //$.ajax(url,[settings]);
20 
21 
22        $(".send_Ajax").click(function(){
23 
24            $.ajax({
25                url:"/handle_Ajax/",
26                type:"POST",
27                data:{username:"Yuan",password:123},
28 
29                success:function(data){
30                    alert(data)
31                },
32 
33                  //=================== error============
34 
35                 error: function (jqXHR, textStatus, err) {
36 
37                         // jqXHR: jQuery增强的xhr
38                         // textStatus: 请求完成状态
39                         // err: 底层通过throw抛出的异常对象,值与错误类型有关
40                         console.log(arguments);
41                     },
42 
43                  //=================== complete============
44 
45                 complete: function (jqXHR, textStatus) {
46                     // jqXHR: jQuery增强的xhr
47                     // textStatus: 请求完成状态 success | error
48                     console.log('statusCode: %d, statusText: %s', jqXHR.status, jqXHR.statusText);
49                     console.log('textStatus: %s', textStatus);
50                 },
51 
52                 //=================== statusCode============
53                 statusCode: {
54                     '403': function (jqXHR, textStatus, err) {
55                         console.log(arguments);  //注意:后端模拟errror方式:HttpResponse.status_code=500
56                      },
57 
58                     '400': function () {
59                     }
60                 }
61 
62            })
63 
64        })
65 
66 </script>
67 </body>
68 </html>
html
 1 import json,time
 2  
 3 def index(request):
 4  
 5     return render(request,"index.html")
 6  
 7 def handle_Ajax(request):
 8     username=request.POST.get("username")
 9     password=request.POST.get("password")
10     print(username,password)
11     time.sleep(10)
12  
13     return HttpResponse(json.dumps("Error Data!"))
view

$.ajax参数

请求参数:

 1 ######################------------data---------################
 2 
 3        data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式
 4              (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。
 5 
 6              function testData() {
 7                $.ajax("/test",{     //此时的data是一个json形式的对象
 8                   data:{
 9                     a:1,
10                     b:2
11                   }
12                });                   //?a=1&b=2
13 ######################------------processData---------################
14 
15 processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
16              那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
17              ,最后得到一个[object,Object]形式的结果。
18             
19 ######################------------contentType---------################
20 
21 contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
22              用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,
23              比如contentType:"application/json",即向服务器发送一个json字符串:
24                $.ajax("/ajax_get",{
25              
26                   data:JSON.stringify({
27                        a:22,
28                        b:33
29                    }),
30                    contentType:"application/json",
31                    type:"POST",
32              
33                });                          //{a: 22, b: 33}
34 
35              注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象
36 
37 
38 ######################------------traditional---------################
39 
40 traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
41               traditional为false会对数据进行深层次迭代;  

 前后端的数据交换:

需求:在前端建立三个input框,在前两个框输入数字的前提下,做完减法之后将结果返回给第三个input框。

1 from django.conf.urls import url
2 from django.contrib import admin
3 from app01 import views
4 
5 urlpatterns = [
6     url(r'^test2/', views.test2),
7     url(r'^Calculation/', views.Calculation),
8 ]
urls.py
 1 from django.shortcuts import render,HttpResponse,redirect
 2 import  time,json
 3 
 4 def test2(request):
 5 
 6     return render(request,"addition.html")
 7 
 8 def Calculation(request):
 9     n1=request.GET.get("jian")
10     n2=request.GET.get("beijian")
11     n1=json.loads(n1)   #将字符串转换为整型
12     n2=json.loads(n2)
13     n3=n1-n2            #数学运算
14 
15     return HttpResponse(n3)
views.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 
 8 <body>
 9 <p>&nbsp&nbsp&nbsp&nbsp&nbsp数:<input type="text" id="d1" name="jian"></p>
10 <p>&nbsp&nbsp数:<input type="text" id="d2" name="beijian"></p>
11 <p>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp:<input type="text" id ="d3" name="cha"></p>
12 <input type="button" value="开始计算" id="d4">
13 
14 </body>
15 <script src="/static/jquery3.2.1.js"></script>
16 <script>
17  $("#d4").click(function(){         {#给标签绑定事件#}
18         $.ajax({
19             url:"/Calculation/",    {#获取请求路径#}
20             type:"GET",               {#获取请求方式#}
21             data:({
22                 jian:$("#d1").val(),    {#获取前端提交的数据#}
23                 beijian:$("#d2").val()
24             }),      {#请求数据,是一个js数据,打包时会ajax会组成 ?name=yuan&pwd=123#}
25             success:function (data) {
26                 $("#d3").val(data);         {#将计算结果返回给第三个input框#}
27                 console.log(data);      {#data接受后台发过来的数据#}
28             }
29         })
30     })
31 </script>
32 </html>
Calculation.html

响应参数:

1 dataType:  预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
2             默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;
3             比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容
4             进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式
5             的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用
6             data Type。
7             dataType的可用值:html|xml|json|text|script
8             见下dataType实例
 1 from django.shortcuts import render,HttpResponse
 2 from django.views.decorators.csrf import csrf_exempt
 3 # Create your views here.
 4 
 5 import json
 6 
 7 def login(request):
 8 
 9     return render(request,'Ajax.html')
10 
11 
12 def ajax_get(request):
13 
14     l=['alex','little alex']
15     dic={"name":"alex","pwd":123}
16 
17     #return HttpResponse(l)      #元素直接转成字符串alexlittle alex
18     #return HttpResponse(dic)    #字典的键直接转成字符串namepwd
19     return HttpResponse(json.dumps(l))
20     return HttpResponse(json.dumps(dic))# 传到前端的是json字符串,要想使用,需要JSON.parse(data)
21 
22 //---------------------------------------------------
23     function testData() {
24 
25         $.ajax('ajax_get', {
26            success: function (data) {
27            console.log(data);
28            console.log(typeof(data));
29            //console.log(data.name);
30            //JSON.parse(data);
31            //console.log(data.name);
32                                      },
33            //dataType:"json",
34                             }
35                        )}
36 
37 注解:Response Headers的content Type为text/html,所以返回的是String;但如果我们想要一个json对象
38     设定dataType:"json"即可,相当于告诉ajax方法把服务器返回的数据转成json对象发送到前端.结果为object
39     当然,
40         return HttpResponse(json.dumps(a),content_type="application/json")
41 
42     这样就不需要设定dataType:"json"了。
43     content_type="application/json"和content_type="json"是一样的!
示例

csrf跨站请求伪造

方式一:

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

方式二:

1 <form>
2 {% csrf_token %}
3 </form>
4     $.ajax({
5         data:{
6             "csrfmiddlewaretoken":$("name='csrfmiddlewaretoken']").val();7 }
8 })        

方式三:

1 <script src="{% static 'js/jquery.cookie.js' %}"></script>
2 $.ajax({
3     headers:{"X-CSRFToken":$.cookie('csrftoken')},
4  
5 })

三种方式的应用场景及使用时的注意事项:

项目 使用方式  应用场景 备注
方式一 在当前页面直接写ajaxSetup方法。 适合单个文件使用  
方式二 将方法写在JS的文件中,在需要使用的页面中导入即可。 适合多个文件使用 除了需要上传大文件的场景都适用
方式三 将方法写在JS的文件中,在需要使用的文件中导入即可。 该方法适合上传大文件的页面使用  

 

JQuery.serialize()

serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串

serialize()函数常用于将表单内容序列化,以便用于AJAX提交。

该函数主要根据用于提交有效表单控件的name和value,将它们拼接为一个可直接用于表单提交的文本字符串,该字符串已经过标准的URL编码处理(字符集编码为UTF-8)。

该函数不会序列化不需要提交的表单控件,这和常规的表单提交行为是一致的。例如:不在<form>标签内的表单控件不会被提交、没有name属性的表单控件不会被提交、带有disabled(禁用)属性的表单控件不会被提交、没有被选中的表单控件不会被提交。

与常规表单提交不一样的是:常规表单一般会提交带有name的按钮控件,而serialize()函数不会序列化带有name的按钮控件。更多详情请点击这里。

语法:

jQuery1.0新增该函数。

1 jQueryObject.serialize()

返回值:

serialize()函数的返回值为String类型,返回将表单元素编码后的可用于表单提交的文本字符串。

请参考下面这段初始HTML代码:

 1 <form name="myForm" action="http://www.365mini.com" method="post">
 2     <input name="uid" type="hidden" value="1" />
 3     <input name="username" type="text" value="张三" />
 4     <input name="password" type="text" value="123456" />
 5     <select name="grade" id="grade">
 6         <option value="1">一年级</option>
 7         <option value="2">二年级</option>
 8         <option value="3" selected="selected">三年级</option>
 9         <option value="4">四年级</option>
10         <option value="5">五年级</option>
11         <option value="6">六年级</option>
12     </select>
13     <input name="sex" type="radio" checked="checked" value="1" />14     <input name="sex" type="radio" value="0" />15     <input name="hobby" type="checkbox" checked="checked" value="1" />游泳
16     <input name="hobby" type="checkbox" checked="checked" value="2" />跑步
17     <input name="hobby" type="checkbox" value="3" />羽毛球
18     <input name="btn" id="btn" type="button" value="点击" />

对<form>元素进行序列化可以直接序列化其内部的所有表单元素。

 //
 序列化<form>内的所有表单元素
// 序列化后的结果:uid=1&username=jack&password=123456&grade=3&sex=1&hobby=1&hobby=2
alert( $("form").serialize() );

 

使用serialize()函数后原本在data中需要逐一name:value的方式改为

data:$("#s1").serialize(),  /#s1位form表单的id

我们也可以直接对部分表单元素进行序列化。

// 序列化所有的text、select、checkbox表单元素
// 序列化后的结果:username=jack&password=123456&grade=3&hobby=1&hobby=2
alert( $(":text, select, :checkbox").serialize() );

serialize()函数通常用于将表单内容序列化,以便通过AJAX方式提交。

1 $("#btn").click( function(){
2 
3     // 将当前表单内容以POST请求的AJAX方式提交到"http://www.365mini.com"
4     $.post( "http://www.365mini.com", $("form").serialize(), function( data, textStatus, jqXHR ){
5         alert( "AJAX提交成功!" );       
6     } );
7         
8 } );

上传文件

python上传文件的方式

 1 def upload(request):
 2     if request.method=="POST":
 3         print("post方式",request.POST)
 4         print("FILES",request.FILES)
 5 
 6         file_obj=request.FILES.get("img")
 7         with open(file_obj.name,"wb")as f:
 8             for i in file_obj:
 9                 f.write(i)
10         return HttpResponse("上传成功")
11     return render(request,"upload.html")
views.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <form action="/upload/" method="post" enctype="multipart/form-data">
10     {% csrf_token %}
11     <p>用户名 <input type="text" name="user"></p>
12     <p>头像<input type="file" name="img"></p>
13     <input type="submit">
14 
15 </form>
16 </body>
17 </html>
upload.html

form表单上传文件

1 <h3>form表单上传文件</h3>
2 
3 
4 <form action="/upload_file/" method="post" enctype="multipart/form-data">
5     <p><input type="file" name="upload_file_form"></p>
6     <input type="submit">
7 </form>
html文件
1 def index(request):
2 
3     return render(request,"index.html")
4 
5 
6 def upload_file(request):
7     print("FILES:",request.FILES)
8     print("POST:",request.POST)
9     return HttpResponse("上传成功!")
views.py

Ajax(FormData)

FormData是什么呢?

XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.
所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         .login_error{
 8             color: red;
 9         }
10     </style>
11 </head>
12 <body>
13 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
14 <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
15 {% csrf_token %}
16 <form action="" id="s1">
17     <p>姓名 <input type="text"></p>
18     <p>密码 <input type="password"></p>
19     <p>头像 <input type="file" id="upload_avatar"></p>
20     <input type="button" onclick="Ajax_send()" value="zhixing">
21 </form>
22 <script>
23 {#    用户验证#}
24     function foo(){
25         $(".login_error").html("")
26     }
27 {#    输入框获取#}
28     function Ajax_send() {
29         var formData = new FormData();
30         formData.append("username",$(":text").val());
31         formData.append("password",$(":password").val());
32         formData.append("img",$("#upload_avatar")[0].files[0]);
33 
34         $.ajax({
35             url:"/get_ajax/",
36             type:"POST",
37             headers:{"X-CSRFToken":$.cookie("csrftoken")},
38             data:formData,
39             contentType:false,
40             processData:false,
41 
42             success:function (data) {
43                 var data=JSON.parse(data);
44                 if(!data["flag"]){      // {#条件不满足的情况下执行以下代码#}
45                     $(".login_error").html("用户名或者密码错误");
46                     setTimeout(foo,3000)
47                 }
48             }
49         })
50 }
51 </script>
52 </body>
53 </html>
html
 1 from django.shortcuts import render,HttpResponse,redirect
 2 import  time,json
 3 
 4 
 5 def index(request):
 6 
 7     return render(request,"index_formdata.html")
 8 
 9 def get_ajax(request):
10     # 获取用户名、密码
11     username=request.POST.get("username")
12     password=request.POST.get("password")
13     # 文件写入
14     if request.method=="POST":
15         print("post方式",request.POST)
16         print("FILES",request.FILES)
17         file_obj=request.FILES.get("img")
18         with open(file_obj.name,"wb")as f:
19             for i in file_obj:
20                 f.write(i)
21         return HttpResponse("上传成功")
views.py
1 from django.conf.urls import url
2 from django.contrib import admin
3 from app01 import views
4 
5 urlpatterns = [
6     url(r'^admin/', admin.site.urls),
7     url(r'^index/', views.index),
8     url(r'^index_formdata/', views.index),
9 ]
urls

 

待更新...

 

posted @ 2017-11-14 09:21  Justin067  阅读(173)  评论(0编辑  收藏  举报
TOP