python Django之Ajax
AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交互式网页应用的网页开发技术方案。
- 异步的JavaScript:
使用 【JavaScript语言】 以及 相关【浏览器提供类库】 的功能向服务端发送请求,当服务端处理完请求之后,【自动执行某个JavaScript的回调函数】。
PS:以上请求和响应的整个过程是【偷偷】进行的,页面上无任何感知。 - XML
XML是一种标记语言,是Ajax在和后台交互时传输数据的格式之一
一、原生AJAX
Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件)。
1、XmlHttpRequest对象介绍
我们一般使用都是通过jquery来引用Ajax(jquery本身没有Ajax功能,它只是Ajax的搬运工)
原生Ajax使用案例如下:
1 from django.conf.urls import url
2 from django.contrib import admin
3 from app01 import views
4 urlpatterns = [
5 url(r'^admin/', admin.site.urls),
6 url(r'^add1/', views.add1),
7 url(r'^add2/', views.add2),
8 url(r'^fake_ajax/', views.fake_ajax),
9 ]
1 from django.shortcuts import render,redirect,HttpResponse
2
3 # Create your views here.
4
5 def add1(request):
6 a1= int(request.POST.get('i1'))
7 a2= int(request.POST.get('i2'))
8 return HttpResponse(a1+a2)
9
10
11 def add2(request):
12 if request.method=='GET':
13 i1=request.GET.get('i1')
14 i2=request.GET.get('i2')
15 print('add2.....')
16 return HttpResponse(i1+i2)
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <input type="text" name="i1">
9 +
10 <input type="text" name="i2">
11 =
12 <input type="text" name="i3">
13 <input type="button" id="btn1" value="jQuery Ajax" onclick="add1()">
14 {#绑定一个点击事件#}
15 <input type="button" id="btn2" value="原生 Ajax" onclick="add2()">
16 {#绑定一个点击事件#}
17 <script src="/static/jquery-3.2.1.js"></script>
18 <script>
19 {#=============================================常用方式========================================#}
20 function add1() {
21 $.ajax({
22 url:'/add1/',
23 type:'POST',
24 data:{'i1':$('#i1').val(),'i2':$('#i2').val()},
25 {#通过jquery获取标签的值#}
26 success:function (arg) {
27 {#回调函数,把arg参数传进去#}
28 $('#i3').val(arg);
29 {#通过jquery设置i3标签的值为arg变量的内容#}
30 }
31 })
32 }
33
34
35 function add2() {
36 {# ==========================================原生Ajax GET方式======================================#}
37 var xhr =new XMLHttpRequest();
38 {#使用原生的Ajax 创建一个对象#}
39 xhr.onreadystatechange=function () {
40 {#为对象设置回调函数#}
41 if(xhr.readyState==4){
42 {#如果对象执行时的数值等于4就执行下边的#}
43 alert(xhr.responseText);
44 {#弹出提示框,框内的内容是对象返回的文本信息#}
45 }
46
47 };
48 xhr.open('GET','/add2/?i1=12&i2=19');
49 {#通过对象创建一个连接 参数(GET传输方式,/add2/传输的地址url ?i1=12&i2=19这是放在url上的数据) 通过get方式传输,把传输的内容放在请求头中,传输到/add2/url#}
50 xhr.send();
51 {#对象调用进行发送#}
52
53
54 {# ==========================================POST方式======================================#}
55 var xhr =new XMLHttpRequest()
56 xhr.onreadystatechange = function () {
57 if (xhr.readyState == 4){
58 alert(xhr.responseText);
59 }
60
61 }
62 };
63 xhr.open('POST','/add2/');
64 {#通过对象创建一个连接 参数(post传输方式,/add2/传输的地址url ) 通过get方式传输,把传输的内容放在请求体中,传输到/add2/url#}
65 xhr.setRequestHeader('Content-Type','application/x-www-from-urlencoded');
66 {#设置请求体,因为后端需要进行请求体的校验#}
67 xhr.send('i1=12&i2=19');
68 {#设置要发送的数据#}
69 </script>
70 </body>
71 </html>
XmlHttpRequest对象的主要方法:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
a. void open(String method,String url,Boolen async) 用于创建请求 参数: method: 请求方式(字符串类型),如:POST、GET、DELETE... url: 要请求的地址(字符串类型) async: 是否异步(布尔类型) b. void send(String body) 用于发送请求 参数: body: 要发送的数据(字符串类型) c. void setRequestHeader(String header,String value) 用于设置请求头 参数: header: 请求头的key(字符串类型) vlaue: 请求头的value(字符串类型) d. String getAllResponseHeaders() 获取所有响应头 返回值: 响应头数据(字符串类型) e. String getResponseHeader(String header) 获取响应头中指定header的值 参数: header: 响应头的key(字符串类型) 返回值: 响应头中指定的header对应的值 f. void abort() 终止请求 |
XmlHttpRequest对象的主要属性:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
a. Number readyState 状态值(整数) 详细: 0-未初始化,尚未调用open()方法; 1-启动,调用了open()方法,未调用send()方法; 2-发送,已经调用了send()方法,未接收到响应; 3-接收,已经接收到部分响应数据; 4-完成,已经接收到全部响应数据; b. Function onreadystatechange 当readyState的值改变时自动触发执行其对应的函数(回调函数) c. String responseText 服务器返回的数据(字符串类型) d. XmlDocument responseXML 服务器返回的数据(Xml对象) e. Number states 状态码(整数),如:200、404... f. String statesText 状态文本(字符串),如:OK、NotFound... |
jQuery Ajax
jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能。
- jQuery 不是生产者,而是大自然搬运工。
- jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject
1 jQuery.get(...)
2 所有参数:
3 url: 待载入页面的URL地址
4 data: 待发送 Key/value 参数。
5 success: 载入成功时回调函数。
6 dataType: 返回内容格式,xml, json, script, text, html
7
8
9 jQuery.post(...)
10 所有参数:
11 url: 待载入页面的URL地址
12 data: 待发送 Key/value 参数
13 success: 载入成功时回调函数
14 dataType: 返回内容格式,xml, json, script, text, html
15
16
17 jQuery.getJSON(...)
18 所有参数:
19 url: 待载入页面的URL地址
20 data: 待发送 Key/value 参数。
21 success: 载入成功时回调函数。
22
23
24 jQuery.getScript(...)
25 所有参数:
26 url: 待载入页面的URL地址
27 data: 待发送 Key/value 参数。
28 success: 载入成功时回调函数。
29
30
31 jQuery.ajax(...)
32
33 部分参数:
34
35 url:请求地址
36 type:请求方式,GET、POST(1.9.0之后用method)
37 headers:请求头
38 data:要发送的数据
39 contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
40 async:是否异步
41 timeout:设置请求超时时间(毫秒)
42
43 beforeSend:发送请求前执行的函数(全局)
44 complete:完成之后执行的回调函数(全局)
45 success:成功之后执行的回调函数(全局)
46 error:失败之后执行的回调函数(全局)
47
48
49 accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
50 dataType:将服务器端返回的数据转换成指定类型
51 "xml": 将服务器端返回的内容转换成xml格式
52 "text": 将服务器端返回的内容转换成普通文本格式
53 "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
54 "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
55 "json": 将服务器端返回的内容转换成相应的JavaScript对象
56 "jsonp": JSONP 格式
57 使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
58
59 如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
60
61 converters: 转换器,将服务器端的内容根据指定的dataType转换类型,并传值给success回调函数
62 $.ajax({
63 accepts: {
64 mycustomtype: 'application/x-some-custom-type'
65 },
66
67 // Expect a `mycustomtype` back from server
68 dataType: 'mycustomtype'
69
70 // Instructions for how to deserialize a `mycustomtype`
71 converters: {
72 'text mycustomtype': function(result) {
73 // Do Stuff
74 return newresult;
75 }
76 },
77 });
1 <!DOCTYPE html>
2 <html>
3 <head lang="en">
4 <meta charset="UTF-8">
5 <title></title>
6 </head>
7 <body>
8
9 <p>
10 <input type="button" onclick="XmlSendRequest();" value='Ajax请求' />
11 </p>
12
13
14 <script type="text/javascript" src="jquery-1.12.4.js"></script>
15 <script>
16
17 function JqSendRequest(){
18 $.ajax({
19 url: "http://c2.com:8000/test/",
20 type: 'GET',
21 dataType: 'text',
22 success: function(data, statusText, xmlHttpRequest){
23 console.log(data);
24 }
25 })
26 }
27
28
29 </script>
30 </body>
31 </html>
二、伪Ajax 顾名思义Ajax就是伪造而成的
由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<!DOCTYPE html><html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <div> <p>请输入要加载的地址:<span id="currentTime"></span></p> <p> <input id="url" type="text" /> <input type="button" value="刷新" onclick="LoadPage();"> </p> </div> <div> <h3>加载页面位置:</h3> <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe> </div> <script type="text/javascript"> window.onload= function(){ var myDate = new Date(); document.getElementById('currentTime').innerText = myDate.getTime(); }; function LoadPage(){ var targetUrl = document.getElementById('url').value; document.getElementById("iframePosition").src = targetUrl; } </script> </body></html> |
1 def fake_ajax(request):
2 print(request.POST)
3 return render(request,'fake_ajax.html',{'obj':'提交成功'})
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <form id="f1" method="POST" action="fake_ajax" target="ifr">
9 {#通过form标签指定以post传输 传输的url是fake_ajax 提交方式使用form表单里的ifr 这样就达到不刷新页面也能把所有信息打包发送#}
10 {% csrf_token %}
11 {#csrf验证#}
12 <input type="text" name="user">
13 <a onclick="submitForm();">提交</a>
14 {#绑定点击事件#}
15 <iframe id="ifr" name="ifr" src="http://www.baidu.com" width="1000px" height="2000px"></iframe>
16 {#使用iframe 标签 访问http://www.baidu.com链接 这样就成功的伪造了一个Ajax#}
17 </form>
18 <script>
19 function submitForm() {
20 {#定义函数#}
21 document.getElementById('ifr').onclick=loadIframe;
22 {#查找id是ifr的标签设置一个点击事件,相当于绑定一个回调函数#}
23 document.getElementById('f1').submit();
24 {#找到id是f1的标签.触发提交函数#}
25 }
26
27 function loadIframe() {
28 {#定义一个相当于回调函数的函数#}
29 alert(123);
30 }
31 </script>
32 </body>
33 </html>
三、使用原生Ajax做一个文件上传功能
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8
9 <h1>原生Ajax上传文件</h1>
10 <input type="file" id="i1">
11 <a onclick="upload1();">上传</a>
12 <div id="container1"></div>
13
14
15
16 {#======================================================原生Ajax上传文件======================================#}
17 function upload1() {
18 {#定义一个点击事件函数#}
19 var formData =new FormData();
20 {#通过FornData 实例化一个对象,FormData是个特殊的功能,可以传输文件和字符串#}
21 formData.append('k1','v1');
22 {#给对象添加俩个值键是k1 值是v1#}
23 formData.append('fafafa',document.getElementById('i1').files[0]);
24 {#给对象添加键是fafafa 值是i1标签的第一个#}
25 var xhr =new XMLHttpRequest();
26 {#实例化一个对象#}
27 xhr.onreadystatechange =function () {
28 {#给对象设置一个回调函数#}
29 if (xhr.readyState==4){
30 {#判断如果xhr对象的执行数字等于4#}
31 var file_path =xhr.responseText;
32 {#获取对象的文本信息赋值给file_path responseText是返回文本字符串#}
33 var tag = document.createElement('img');
34 {#创建一个img标签,标签名字是tag#}
35 tag.src='/'+file_path;
36 {#通过标签名创建一个图片路径#}
37 document.getElementById('container1').appendChild(tag);
38 {#通过id找到container1标签 然后再通过标签的名添加个子标签#}
39 }
40 }
41 };
42 xhr.open('POST','/upload/');
43 {#对象调用open方法创建一个连接,参数post传输方式 /upload/传输地址url#}
44 xhr.send(formData);
45 {#通过对象发送FormData实例化的对象#}
46
47
48 </script>
49 </body>
50 </html>
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8
9
10 <h1>JQuery Ajax上传文件</h1>
11 <input type="file" id="i2">
12 <a onclick="upload2();">上传</a>
13 <div id="container2"></div>
14
15
16 {#======================================================JQuery Ajax上传文件======================================#}
17 function upload2() {
18 {#定义一个函数#}
19 var formData =new FormData();
20 {#通过FornData 实例化一个对象,FormData是个特殊的功能,可以传输文件和字符串#}
21 formData.append('k1','v1');
22 {#给对象添加俩个值键是k1 值是v1#}
23 formData.append('fafafa',$('#i2')[0].files[0]);
24 {#把fafafa作为键 值是id等于i2的标签转换成Dom对象的第一个#}
25 $.ajax({
26 url:'/upload/',
27 type:'POST',
28 data:formData,
29 contentType:false,
30 {#告诉后端不进行请求头设置#}
31 processData:false,
32 {#告诉后端不进行请求头设置#}
33 success:function (arg) {
34 {#回调函数#}
35 var tag =document.createElement('img');
36 {#创建一个img标签名称为tag#}
37 tag.src='/'+arg;
38 {#为名字为tag的标签设置路径#}
39 $('#container2').append(tag);
40 {#为id是container2标签的添加名字是tag的标签为子标签#}
41 }
42 })
43
44 }
45
46
47
48
49 </script>
50 </body>
51 </html>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> <div id="container1"></div> <h1>JQuery Ajax上传文件</h1> <input type="file" id="i2"> <a onclick="upload2();">上传</a> <div id="container2"></div> <h1>伪 Ajax上传文件</h1> <form id="f1" method="POST" action="/upload/" target="ifr" enctype="multipart/form-data"> <iframe id="ifr" name="ifr" src="" style="display: none"></iframe> <input type="file" name="fafafa"> <a onclick="upload3();">上传</a> </form> <div id="container3"></div> <script src="/static/jquery-3.2.1.js"></script> <script>{#======================================================原生Ajax上传文件======================================#} function upload1() {{#定义一个点击事件函数#} var formData =new FormData();{#通过FornData 实例化一个对象,FormData是个特殊的功能,可以传输文件和字符串#} formData.append('k1','v1');{#给对象添加俩个值键是k1 值是v1#} formData.append('fafafa',document.getElementById('i1').files[0]);{#给对象添加键是fafafa 值是i1标签的第一个#} var xhr =new XMLHttpRequest();{#实例化一个对象#} xhr.onreadystatechange =function () {{#给对象设置一个回调函数#} if (xhr.readyState==4){{#判断如果xhr对象的执行数字等于4#} var file_path =xhr.responseText;{#获取对象的文本信息赋值给file_path responseText是返回文本字符串#} var tag = document.createElement('img');{#创建一个img标签,标签名字是tag#} tag.src='/'+file_path;{#通过标签名创建一个图片路径#} document.getElementById('container1').appendChild(tag);{#通过id找到container1标签 然后再通过标签的名添加个子标签#} } } }; xhr.open('POST','/upload/');{#对象调用open方法创建一个连接,参数post传输方式 /upload/传输地址url#} xhr.send(formData);{#通过对象发送FormData实例化的对象#}{#======================================================JQuery Ajax上传文件======================================#} function upload2() {{#定义一个函数#} var formData =new FormData();{#通过FornData 实例化一个对象,FormData是个特殊的功能,可以传输文件和字符串#} formData.append('k1','v1');{#给对象添加俩个值键是k1 值是v1#} formData.append('fafafa',$('#i2')[0].files[0]);{#把fafafa作为键 值是id等于i2的标签转换成Dom对象的第一个#} $.ajax({ url:'/upload/', type:'POST', data:formData, contentType:false,{#告诉后端不进行请求头设置#} processData:false,{#告诉后端不进行请求头设置#} success:function (arg) {{#回调函数#} var tag =document.createElement('img');{#创建一个img标签名称为tag#} tag.src='/'+arg;{#为名字为tag的标签设置路径#} $('#container2').append(tag);{#为id是container2标签的添加名字是tag的标签为子标签#} } }) } function upload3() {{# 定义一个函数#} document.getElementById('ifr').onload=loadIframe;{# 查找id是ifr的标签并设置在加载时调用loadIframe函数#} document.getElementById('f1').submit();{#查找id是f1的标签并启动#} } function loadIframe() {{#定义一个函数#} var content =document.getElementById('ifr').contentWindow.document.body.innerText;{#查找id是ifr的标签,的window内容的请求体的文本信息#} var tag = document.createElement('img');{#创建一个img标签并设置标签名字是tag#} tag.src='/'+content;{#找到名字是tag标签设置路径#} $('#container3').append(tag);{#找到id 是container3的标签添加一个名字是tag的标签tag#} } </script></body></html> |

浙公网安备 33010602011771号