一、AJAX做用javascript
1. AJAX 是一種在無需從新加載整個網頁的狀況下,可以更新部分網頁的技術。html
2. AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。java
3. AJAX 不是新的編程語言,而是一種使用現有標準的新方法。jquery
二、AJAX與傳統開發模式區別web
ajax開發模式:頁面將用戶的操做經過ajax引擎與服務器進行通訊,將返回的結果給ajax引擎,而後ajax將數據插入指定位置。ajax
傳統的開發模式:用戶的每一次操做都觸發一次返回服務器的HTTP請求,服務器作出處理後,返回一個html頁面給用戶。django
三、AJAX請求的三種方法編程
1. jQuery Ajax:本質 XMLHttpRequest 或 ActiveXObjectjson
2. 原生Ajax:主要就是使用 【XmlHttpRequest】對象來完成請求的操做,該對象在主流瀏覽器中均存在跨域
3. 「僞」AJAX:因爲HTML標籤的iframe標籤具備局部加載內容的特性,因此可使用其來僞造Ajax請求
一、JQuery AJAX說明
一、jQuery其實就是一個JavaScript的類庫,其將複雜的功能作了上層封裝,使得開發者能夠在其基礎上寫更少的代碼實現更多的功能
二、jQuery Ajax本質 XMLHttpRequest 或 ActiveXObject
二、使用JQuery AJAX發送數據
from django.shortcuts import render,HttpResponse import json def login(request): if request.method == 'GET': return render(request,'login.html') elif request.method == 'POST': print(request.POST) #{'name': ['root'], 'pwd': ['123']} ret = {'code':True,'data':None} return HttpResponse(json.dumps(ret))
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form id="add_form"> <input type="text" name="user" placeholder="用戶名"> <input type="text" name="pwd" placeholder="密碼"> <span id="jquery_ajax">JQuery Ajax提交</span> </form> <script src="/static/jquery-1.12.4.js"></script> <script> $('#jquery_ajax').click(function(){ $.ajax({ url: '/login/', // data: {'user': 123,'host_list': [1,2,3,4]}, // 也能夠這樣穿數據給後臺 data: $('#add_form').serialize(), //拿到form表單提交的全部內容 type: "POST", dataType: 'JSON', // 讓JQuery將data先JSON後再發送到後臺 traditional: true, //若是發送的是列表告訴JQuery也發送到後臺 success: function(data, statusText, xmlHttpRequest){ if(data.code == true){ console.log('返回登陸後的頁面'); }else { console.log('在頁面上添加錯誤提示信息'); } }, error: function () { //只有當發送數據,後臺沒有捕捉到的未知錯誤才執行error函數 } }) }); </script> </body> </html>
三、JQuery ajax藉助FormData上傳文件(藉助FormData低版本ie不支持)
from django.shortcuts import render,HttpResponse import json def upload(request): return render(request,'upload.html') def upload_file(request): username = request.POST.get('username') fafafa = request.FILES.get('fafafa') print(username,fafafa) with open(fafafa.name,'wb') as f: for item in fafafa.chunks(): f.write(item) ret = {'code':True,'data':request.POST.get('username')} return HttpResponse(json.dumps(ret))
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .upload{ display: inline-block; padding: 10px; background-color: brown; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 90; } .file{ width: 60px; height: 30px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 100; opacity: 0; } </style> </head> <body> {# 爲了讓咱們的上傳圖標好看,能夠用咱們的a標籤顯示到上傳標籤的外面 #} <div style="position: relative;width: 60px;height: 40px"> <input class="file" type="file" id="fafafa" name="afafaf"> <a class="upload">上傳</a> </div> <input type="button" value="提交jQuery" onclick="fqSubmit();"> <script src="/static/jquery-1.12.4.js"></script> <script> function fqSubmit(){ var file_obj = document.getElementById('fafafa').files[0]; var fd = new FormData(); // FormData對象能夠傳字符串,也能夠傳文件對象 fd.append('username','root'); fd.append('fafafa',file_obj); var xhr = new XMLHttpRequest(); $.ajax({ url:'/upload_file/', type:'POST', data:fd, //jquery Ajax上傳文件必須執定processData,contentType參數 processData:false, //告訴JQuery不要特殊處理這個數據 contentType:false, //告訴JQuery不要設置內容格式 success:function(arg,a1,a2){ console.log(111,arg); //後臺返回的數據 console.log(222,a1); //執行狀態:sucess(fail) console.log(333,a2); //對象 } }) } </script> </body> </html>
四、當框架加載完成發送ajax發送請求獲取數據
// 當框架加載完成後執行此函數 window.onload = function(){ var deptid = $('[name="approvetype"]').val(); $.ajax({ url: '{% url "workordermanager:parse_deptid" %}', data: {'deptid': deptid}, // 也能夠這樣穿數據給後臺 type: "get", dataType: 'JSON', // 讓JQuery將data先JSON後再發送到後臺 traditional: true, //若是發送的是列表告訴JQuery也發送到後臺 success: function(data, statusText, xmlHttpRequest){ if(data.code == true){ $('[name="approvetype"]').val(data.data); }else { console.log('在頁面上添加錯誤提示信息'); } }, error: function () { //只有當發送數據,後臺沒有捕捉到的未知錯誤才執行error函數 } }) }
一、原生AJAX說明
1. 原生Ajax主要就是使用 【XmlHttpRequest】對象來完成請求的操做
2. 該對象在主流瀏覽器中均存在(除早起的IE),Ajax首次出現IE5.5中存在(ActiveX控件)
二、XmlHttpRequest對象方法和屬性
// 一、void open(String method,String url,Boolen async) 1)做用:用於建立請求 2)參數: method: 請求方式(字符串類型),如:POST、GET、DELETE... url: 要請求的地址(字符串類型) async: 是否異步(布爾類型) // 二、void send(String body) 1)做用:用於發送請求 2)參數: body: 要發送的數據(字符串類型) // 三、void setRequestHeader(String header,String value) 1)做用:用於設置請求頭 2)參數: header: 請求頭的key(字符串類型) vlaue: 請求頭的value(字符串類型) // 四、String getAllResponseHeaders() 1)做用:獲取全部響應頭 2)返回值: 響應頭數據(字符串類型) // 五、String getResponseHeader(String header) 1)做用:獲取響應頭中指定header的值 2)參數: header: 響應頭的key(字符串類型) 3)返回值: 響應頭中指定的header對應的值 // 六、oid abort() 1)做用: 終止請求
//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...
三、使用原生AJAX發送數據(send方法發送)
from django.shortcuts import render,HttpResponse import json def login(request): if request.method == 'GET': return render(request,'login.html') elif request.method == 'POST': print(request.POST) #{'name': ['root'], 'pwd': ['123']} ret = {'code':True,'data':None} return HttpResponse(json.dumps(ret))
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="button" value="ajax1" onclick="Ajax1()"> <script> // 使用原生ajax發送數據 function Ajax1(){ // var xhr = GetXHR(); //(瀏覽器兼容性能夠這樣建立xhr對象) //1 new關鍵字建立JavaScript的XMLHttpRequest對象xhr var xhr = new XMLHttpRequest(); //建立xhr對象(瀏覽器兼容性) //2 以get方式發數據給ajax_json,true表示支持異步 xhr.open('POST','/login/',true); //open就是xhr對象的方法 //3 onreadystatechange是:回調函數,當readyState的值改變時自動觸發執行其對應的匿名函數 xhr.onreadystatechange = function(){ if(xhr.readyState == '4'){ // 只有狀態爲4時才執行 表示已經接收完畢 var obj = JSON.parse(xhr.responseText); // xhr.responseText就是服務器端的返回值 console.log(obj); //獲取返回值:{code: true, data: null} } }; //4 發送請求頭 CSRF中用的就是這個 xhr.setRequestHeader('k1','v1'); //5 後臺要想得到xhr.send數據,必須在這裏設置請求頭 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); //6 發送的字符串內容 xhr.send("name=root;pwd=123"); } // 原生ajax兼容ie低版本才使用這個方法建立XMLHttpRequest對象 function GetXHR(){ var xhr = null; //先設置xhr對象爲null if(XMLHttpRequest){ xhr = new XMLHttpRequest(); //若是有XMLHttpRequest就設置 }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); //沒有就設置成微軟的 } return xhr; } </script> </body> </html>
四、原生ajax藉助FormData上傳文件(藉助FormData低版本ie不支持)
from django.shortcuts import render,HttpResponse import json def upload(request): return render(request,'upload.html') def upload_file(request): username = request.POST.get('username') fafafa = request.FILES.get('fafafa') print(username,fafafa) with open(fafafa.name,'wb') as f: for item in fafafa.chunks(): f.write(item) ret = {'code':True,'data':request.POST.get('username')} return HttpResponse(json.dumps(ret))
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .upload{ display: inline-block; padding: 10px; background-color: brown; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 90; } .file{ width: 60px; height: 30px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 100; opacity: 0; } </style> </head> <body> {# 爲了讓咱們的上傳圖標好看,能夠用咱們的a標籤顯示到上傳標籤的外面 #} <div style="position: relative;width: 60px;height: 40px"> <input class="file" type="file" id="fafafa" name="afafaf"> <a class="upload">上傳</a> </div> <input type="button" value="提交XHR" onclick="xhrSubmit();"> <script src="/static/jquery-1.12.4.js"></script> <script> // 原生ajax上傳文件 function xhrSubmit(){ var file_obj = document.getElementById('fafafa').files[0]; var fd = new FormData(); // FormData對象能夠傳字符串,也能夠傳文件對象 fd.append('username','root'); fd.append('fafafa',file_obj); var xhr = new XMLHttpRequest(); xhr.open('POST','/upload_file/',true); //open就是xhr對象的方法 xhr.onreadystatechange = function(){ if(xhr.readyState == '4'){ var obj = JSON.parse(xhr.responseText); console.log(obj); } }; xhr.send(fd); } </script> </body> </html>
一、說明
1. 因爲HTML標籤的iframe標籤具備局部加載內容的特性,因此可使用其來僞造Ajax請求。
二、使用僞AJAX發送數據
from django.shortcuts import render,HttpResponse import json def login(request): if request.method == 'GET': return render(request,'login.html') elif request.method == 'POST': print(request.POST) #{'name': ['root'], 'pwd': ['123']} ret = {'code':True,'data':None} return HttpResponse(json.dumps(ret))
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {#1 target="ifm1 就讓form和iframe創建關係,表單就會經過iframe提交數據到後臺 #} {#2 能夠給submit綁定一個事件,當點擊時才綁定iframeLoad事件 #} <form action="/login/" method="POST" target="ifm1"> <iframe name="ifm1" id="ifm1" style="display: none"></iframe> <input type="text" name="username"> <input type="text" name="email"> <input type="submit" value="Form提交" onclick="submitForm();"> </form> <script src="/static/jquery-1.12.4.js"></script> <script> //1 使用iframe提交數據,後臺返回數據放到iframe中了,須要拿到數據 //2 只有當點擊提"Form提交"纔會觸發綁定iframe 的load事件 //3 只有當後臺返回數據後,纔會自動觸發iframe的load事件 function submitForm(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); // contents()中就能夠獲取到後臺返回給iframe的內容了 var obj = JSON.parse(text); //將字符串轉換成json數據 console.log(obj) }) } </script> </body> </html>
三、iframe僞ajax上傳圖片及預覽(能夠兼容全部瀏覽器)
from django.shortcuts import render,HttpResponse import json import os def upload_file(request): if request.method == 'POST': username = request.POST.get('username') fafafa = request.FILES.get('fafafa') img_path = os.path.join('static\image',fafafa.name) print(img_path) with open(img_path,'wb') as f: for item in fafafa.chunks(): f.write(item) ret = {'code':True,'data':img_path} return HttpResponse(json.dumps(ret)) return render(request,'upload_file.html')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/upload_file/" method="POST" target="ifm1" enctype="multipart/form-data"> <iframe name="ifm1" id="ifm1" style="display: none"></iframe> <input type="file" name="fafafa"> <input type="submit" value="iframe提交" onclick="iframeForm();"> </form> <div id="preview"></div> <script src="/static/jquery-1.12.4.js"></script> <script> function iframeForm(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); //將字符串轉換成json數據 var imgTag = document.createElement('img'); //建立image標籤 $('#preview').empty(); imgTag.src='/'+obj.data; //上傳後圖片路徑 $('#preview').append(imgTag); }) } </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form id="fm" action="/upload_file/" method="POST" target="ifm1" enctype="multipart/form-data"> <iframe name="ifm1" id="ifm1" style="display: none"></iframe> <input type="file" name="fafafa" onchange="iframeForm();" id="publish_file" style="display: none"> <a onclick="document.getElementById('publish_file').click();">上傳圖片</a> </form> <div id="preview"></div> <script src="/static/jquery-1.12.4.js"></script> <script> function iframeForm(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); //將字符串轉換成json數據 var imgTag = document.createElement('img'); //建立image標籤 $('#preview').empty(); imgTag.src='/'+obj.data; //上傳後圖片路徑 $('#preview').append(imgTag); }); document.getElementById('fm').submit(); } </script> </body> </html>
一、jsonp跨域請求原理
1. 因爲瀏覽器存在同源策略機制,同源策略阻止經過js經過瀏覽器設置另外一個源加載的文檔的屬性。
2. 好比如今訪問 http://127.0.01/index 頁面,在index頁面中經過js發送請求獲取 http://tom.com/login/ 頁面的數據會被瀏覽器阻止
3. 因爲同源策略是瀏覽器的限制,因此請求的發送和響應是能夠進行,只不過瀏覽器不接受返回來的數據罷了
4. 瀏覽器同源策略僅制約XmlHttpRequest,不會制約 img、iframe、script等具備src屬性的標籤
5. JSONP(JSON with Padding是JSON的一種「使用模式」),利用script標籤的src屬性實現jsonp跨域請求
6. JSONP實質就是經過scrip的src屬性向其餘域請求數據,這樣就能夠在網頁中獲取到遠端路徑的數據了
二、實現jsonp跨域請求測試分爲如下幾步
1. 首先須要創建第兩個Django項目MyNewDay25 和 anotherDomainProject
2.從MyNewDay25 的Django項目經過AJAX,向 anotherDomainProject項目請求數據
3. 這裏由於在同一臺計算機中測試,因此將anotherDomainProject 監聽端口改成8001
4. 爲了實現不一樣域名的效果,修改計算機hosts記錄:
路徑: C:\Windows\System32\drivers\etc\hosts
添加: 127.0.0.1 tom.com
目的:經過 http://tom.com:8001/another_domain_project/?callback=list' 訪問anotherDomainProject
二、MyNewDay25 項目中發送請求給anotherDomainProject獲取數據
1. MyNewDay25代碼
說明:當咱們訪問MyNewDay25項目的: http://127.0.0.1:8000/get_data/ 時就會使用ajax到
http://tom.com:8001/another_domain_project/ 獲取數據,而後經過console.log打印出來
from django.shortcuts import render,HttpResponse def get_data(request): return render(request,'get_data.html')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="button" value="獲取數據" onclick="getContent();" /> <script src="/static/jquery-1.12.4.js"></script> <script> function getContent(){ // 1. 使用原生js的src屬性跨域請求數據 var tag = document.createElement('script'); tag.src = 'http://tom.com:8001/another_domain_project/?callback=list'; // tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?calback=list&_=1454376870403'; document.head.appendChild(tag); document.head.removeChild(tag); // 2. 使用ajax實現jsonp跨域請求 $.ajax({ url: 'http://tom.com:8001/another_domain_project/', type: 'POST', dataType: 'jsonp', // 下面的兩句就至關於上面再URL中寫:?callback=list jsonp: 'callback', jsonpCallback: 'list' }) } // 3.這個函數就是當數據返回後使用list函數處理:arg就是跨域請求來的數據 function list(arg){ console.log(arg); } </script> </body> </html>
2. anotherDomainProject代碼
ALLOWED_HOSTS = ['tom.com','127.0.0.1',]
from django.shortcuts import render,HttpResponse def another_domain_project(request): # 請求端發送AJAX請求路徑:http://tom.com:8001/another_domain_project/?callback=list func = request.GET.get('callback') # 獲取請求端回調函數名(這裏名字是:list,字符串格式) content = '%s(1000000)'%(func) # 返回給請求端內容:list(1000000), 在請求端就會調用js中的list()函數了 return HttpResponse(content)
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.set_header('Access-Control-Allow-Origin', "") self.render('get_data.html') settings = { 'template_path': 'template', 'static_path': 'static', 'static_url_prefix': '/static/', } application = tornado.web.Application([ (r"/get_date", MainHandler), ], **settings) if __name__ == "__main__": application.listen(8000) print('http://127.0.0.1:8000/get_date') tornado.ioloop.IOLoop.instance().start()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" onclick="AjaxRequest()" value="跨域Ajax" /> <div id="container"></div> <script src="/static/jquery-1.12.4.js" type="text/javascript"></script> <script type="text/javascript"> function AjaxRequest() { $.ajax({ // 下面這個路徑是江西衛視界面菜單的json數據 url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403', type: 'GET', dataType: 'jsonp', jsonp: 'callback', jsonpCallback: 'list', success: function (data) { $.each(data.data,function(i){ var item = data.data[i]; var str = "<p>"+ item.week +"</p>"; $('#container').append(str); $.each(item.list,function(j){ var temp = "<a href='" + item.list[j].link +"'>" + item.list[j].name +" </a><br/>"; $('#container').append(temp); }); $('#container').append("<hr/>"); }) } }); } </script> </body> </html>