在前一篇的知識儲備下,開始接受AJAX
的的洗禮吧。javascript
AJAX(Asynchronous Javascript And XML)翻譯成中文就是「異步的Javascript和XML」。html
即便用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(固然,傳輸的數據不僅是XML)。java
AJAX 不是新的編程語言,而是一種使用現有標準的新方法。python
注意,接下來纔是重點!!!jquery
舉個栗子:ajax
咱們常常會在網站搜圖片或者看文章,當你不斷下拉的時候,拉到頁面底部,突然!網頁又加載出來一堆圖片和文章,這種狀況,其實就是咱們的AJAX在幹活,是否是內心有點數了?django
第一,AJAX 最大的優勢:編程
第二,AJAX工做原理:json
不須要任何瀏覽器插件,但須要用戶容許JavaScript在瀏覽器上執行。後端
有人會問,圖片中的「XHR」是什麼東西,別急,咱們慢慢來。
所謂的「XHR」(瀏覽器內置對象」XMLHttpRequest 」),也就是Ajax功能實現所依賴的對象,AJAX就是經過瀏覽器的內置對象XHMHttpResquest
來發送異步請求的,異步請求不會妨礙客戶端的任何操做。
XHR至關因而一個通訊兵,來負責客戶端與服務器之間的通訊傳輸。
舉個形象生動的例子:
要打仗了,前方陣地(客服端)不可能只等着通訊兵(XHR)傳遞消息其餘什麼也不幹吧,因此前方陣地還在幹着本身的事情而後派通訊兵去請求後方指揮部(服務器)的命令,指揮部下達命令指揮,通訊兵再把命令傳到前方陣地,而後前方陣地再執行命令相關的操做(客戶端把數據渲染到頁面),這也就是Ajax的異步原理。
所謂的同步就是前方陣地和通訊兵一塊兒去向服務器請求數據,直到通訊兵請求到數據,我纔開始渲染頁面,在請求的過程當中頁面一直是白屏等待的。
等一下,這個同步異步你們有沒有回想起咱們以前在學習線程進程的時候,也有同步異步。
其實說得簡單點,就是你在燒水,同步就是你啥也不幹就等水開,異步則是水壺一丟去幹別的事了。
頁面輸入兩個整數,經過AJAX傳輸到後端計算出結果並返回。
#HTML部分代碼# <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <input type="text" id="i1"> + <input type="text" id="i2"> = <input type="text" id="i3"> <button id="b1">Ajax Test</button> <script src="/static/jquery-3.3.1.min.js"></script> <script> $('#b1').click(function () { $.ajax({ url:'', type:'POST', data:{i1:$('#i1').val(),i2:$('#i2').val()}, success:function (data) { $('#i3').val(data) } }) }) </script> </body> </html>
#views.py def ajax_test(request): if request.method=='POST': i1=request.POST.get('i1') i2=request.POST.get('i2') ret=int(i1)+int(i2) return HttpResponse(ret) return render(request,'ajax_test.html') views.py
#urls.py from django.conf.urls import url from app01 import views urlpatterns=[ url(r'^ajax_test/',views.ajax_test), ]
其實除了上文提到的頁面加載用到的AJAX技術,還有一些常見的例子:
當文件框發生了輸入變化時,使用AJAX技術向服務器發送一個請求,而後服務器會把查詢到的結果響應給瀏覽器,最後再把後端返回的結果展現出來。
具體步驟:
當輸入用戶名後,把光標移動到其餘表單項上時
瀏覽器會使用AJAX技術向服務器發出請求,服務器會查詢名爲lemontree7777777的用戶是否存在
最終服務器返回true表示名爲lemontree7777777的用戶已經存在
瀏覽器在獲得結果後顯示「用戶名已被註冊!」
整個過程當中頁面沒有刷新,只是局部刷新了
在請求發出後,瀏覽器不用等待服務器響應結果就能夠進行其餘操做
AJAX幹掉了Back和History功能,即對瀏覽器機制的破壞。
安全問題技術同時也對IT企業帶來了新的安全威脅。
對搜索引擎的支持比較弱。若是使用不當,AJAX會增大網絡數據的流量,從而下降整個系統的性能。
這缺點也太長了!!!!你們只須要記住AJAX的局部刷新優勢就行,缺點在優勢面前就顯得...你懂的!
最基本的jQuery發送AJAX請求示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .hide { display: none; } </style> </head> <body> <p> <input type="text" class="user"> <span class="hide" style="color: red">用戶名已存在</span> </p> <script src="/static/jquery-3.3.1.min.js"></script> {#下面這一項是基於jQuery的基礎上自動給咱們的每個ajax綁定一個請求頭信息,相似於form表單提交post數據必需要有的csrf_token同樣#} {#不然個人Django中間件裏面的校驗csrf_token那一項會認爲你這個請求不是合法的,阻止你的請求#} <script src="/static/setup_Ajax.js"></script> <script> //給input框綁定一個失去焦點的事件 $('.user').blur(function () { //$.ajax爲固定用法,表示啓用ajax $.ajax({ //url後面跟的是你這個ajax提交數據的路徑,向誰提交,不寫就是向當前路徑提交 url:'', //type爲標定你這個ajax請求的方法 type:'POST', //data後面跟的就是你提交給後端的數據 data:{'username':$(this).val()}, //success爲回調函數,參數data即後端給你返回的數據 success:function (data) { ret=JSON.parse(data); if (ret['flag']){ $('p>span').removeClass('hide'); } } }) }); </script> </body> </html>
def index(request): if request.method=='POST': ret={'flag':False} username=request.POST.get('username') if username=='JBY': ret['flag']=True import json return HttpResponse(json.dumps(ret)) return render(request,'index.html')
data參數中的鍵值對,若是值不爲字符串,須要將其轉換成字符串類型。
$("#b1").on("click", function () { $.ajax({ url:"/ajax_add/", type:"GET", data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])}, success:function (data) { $("#i3").val(data);kkk } }) })
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=q1mi&password=123456"); xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { alert(xmlHttp.responseText); } }; };
csrf_token
不管是ajax
仍是誰,只要是向我Django
提交post
請求的數據,都必須校驗csrf_token
來防僞跨站請求。
那麼如何在個人ajax
中弄這個csrf_token
呢???
我又不像form
表單那樣能夠在表單內部經過一句{% csrf_token %}
就搞定了......
經過獲取隱藏的input標籤中的csrfmiddlewaretoken
值,放置在data中發送。
$.ajax({ url: "/cookie_ajax/", type: "POST", data: { "username": "Tonny", "password": 123456, "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val() // 使用JQuery取出csrfmiddlewaretoken的值,拼接到data中 }, success: function (data) { console.log(data); } })
經過獲取返回的cookie
中的字符串,放置在請求頭中發送。
注意:須要引入一個jquery.cookie.js插件。
$.ajax({ url: "/cookie_ajax/", type: "POST", headers: {"X-CSRFToken": $.cookie('csrftoken')}, // 從Cookie取csrf_token,並設置ajax請求頭 data: {"username": "Ada", "password": 123456}, success: function (data) { console.log(data); } })
或者用本身寫一個getCookie
方法:
function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken');
每一次都這麼寫太麻煩了,可使用$.ajaxSetup()方法爲ajax請求統一設置。
function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });
將下面的文件配置到你的Django項目的靜態文件中,在html頁面上經過導入該文件便可自動幫咱們解決ajax提交post數據時校驗csrf_token的問題。
(導入該配置文件以前,須要先導入jQuery,由於這個配置文件內的內容是基於jQuery來實現的)
太多啦,重要的「Ajax傳Json格式數據」、「Ajax上傳文件」部分,下篇見:)