74、django之ajax補充,74djangoajax
之前的ajax使用都是依據jquery來使用的,本篇會先分析ajax的原生的js代碼實現,還有jsonp的介紹和最終使用。
本篇導航:
一、js實現的ajax
1、XMLHttpRequest對象
其實AJAX就是在Javascript中多添加了一個對象:XMLHttpRequest對象。所有的非同步互動都是使用XMLHttpServlet對象完成的。
var xmlHttp = new XMLHttpRequest() //(大多數瀏覽器都支援DOM2規範)
相容性解決
function createXMLHttpRequest() { var xmlHttp; // 適用於大多數瀏覽器,以及IE7和IE更高版本 try{ xmlHttp = new XMLHttpRequest(); } catch (e) { // 適用於IE6 try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { // 適用於IE5.5,以及IE更早版本 try{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){} } } return xmlHttp;}
2、使用流程
1)擷取XMLHttpRequest對象
var xmlHttp = createXMLHttpRequest();
2)串連伺服器
xmlHttp.open("get", "/ajax_get/?a=1", true);xmlHttp.open("post", "/ajax_get/");//第三個參數可以不給,預設值為true,表示非同步請求;
3)佈建要求頭
xmlHttp.setRequestHeader("Content-Type","application/json");var ele_csrf=document.getElementsByName("csrfmiddlewaretoken")[0]; //html代碼{% csrf_token %}xmlHttp.setRequestHeader("X-CSRFToken",ele_csrf.value); //csrf防禦的一個解決方案
4)發送資料
xmlHttp.send(null) ; // 請求體資料
沒有資料需要發送null否則瀏覽器可能報錯
5)接受伺服器響應
XMLHttpRequest對象有一個onreadystatechange事件,它會在XMLHttpRequest對象的狀態發生變化時被調用。下面介紹一下XMLHttpRequest對象的5種狀態:
0:初始化未完成狀態,只是建立了XMLHttpRequest對象,還未調用open()方法;
1:請求已開始,open()方法已調用,但還沒調用send()方法;
2:請求發送完成狀態,send()方法已調用;
3:開始讀取伺服器響應;
4:讀取伺服器響應結束。
onreadystatechange事件會在狀態為5種狀態發生變化時引發。所以會發生4次
xmlHttp.onreadystatechange = function() { alert('hello'); 代碼會被執行四次,對應XMLHttpRequest的四次變化};
我們只關心最後一種狀態,即讀取伺服器響應結束時,用戶端才會做出改變。我們可以通過XMLHttpRequest對象的readyState屬性來得到XMLHttpRequest對象的狀態。
xmlHttp.onreadystatechange = function() { if(xmlHttp.readyState == 4) { alert('hello'); }};
其實我們還要關心伺服器響應的狀態代碼是否為200,其伺服器響應為404,或500,那麼就表示請求失敗了。我們可以通過XMLHttpRequest對象的status屬性得到伺服器的狀態代碼。
xmlHttp.onreadystatechange = function() { if(xmlHttp.readyState == 4 && xmlHttp.status == 200) { alert(xmlHttp.responseText); }};
二、同源策略與Jsonp
1、同源策略
同源策略,它是由Netscape提出的一個著名的安全性原則。現在所有支援JavaScript 的瀏覽器都會使用這個策略。所謂同源是指,網域名稱,協議,連接埠相同。當一個瀏覽器的兩個tab頁中分別開啟來 百度和Google的頁面當瀏覽器的百度tab頁執行一個指令碼的時候會檢查這個指令碼是屬於哪個頁面的,即檢查是否同源,只有和百度同源的指令碼才會被執行。如果非同源,那麼在請求資料時,瀏覽器會在控制台中報一個異常,提示拒絕訪問。
2、最終實現
1)8001的html
<script> function f(){ $.ajax({ url:"http://127.0.0.1:7766/SendAjax/", dataType:"jsonp", jsonp: 'callbacks', jsonpCallback:"SayHi" }); } function SayHi(arg){ alert(arg); }</script>
2)8002的views
def SendAjax(request): import json # dic={"k1":"v1"} return HttpResponse("func('yuan')") # return HttpResponse("func('%s')"%json.dumps(dic))
3、通過回呼函數來處理
8001的html
<script> function f(){ $.ajax({ url:"http://127.0.0.1:7766/SendAjax/", dataType:"jsonp", //必須有,告訴server,這次訪問要的是一個jsonp的結果。 jsonp: 'callbacks', //jQuery協助隨機產生的:callbacks="wner" success:function(data){ alert("hi "+data) } }); }</script>
8002的views不改動
jsonp: 'callbacks'就是定義一個存放回呼函數的鍵,jsonpCallback是前端定義好的回呼函數方法名'SayHi',server端接受callback鍵對應值後就可以在其中填充資料打包返回了; jsonpCallback參數可以不定義,jquery會自動定義一個隨機名發過去,那前端就得用回呼函數來處理對應資料了。利用jQuery可以很方便的實現JSONP來進行跨域訪問。
注意 JSONP一定是GET請求
4、應用
<input type="button" onclick="AjaxRequest()" value="跨域Ajax" /><div id="container"></div><script type="text/javascript"> function AjaxRequest() { $.ajax({ 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>