【1029 | Day55】AJAX簡介及jQuery/Js實現AJAX

1. AJAX簡介

在前一篇的知識儲備下,開始接受AJAX的的洗禮吧。javascript

表情

AJAX(Asynchronous Javascript And XML)翻譯成中文就是「異步的Javascript和XML」。html

即便用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(固然,傳輸的數據不僅是XML)java

AJAX 不是新的編程語言,而是一種使用現有標準的新方法。python

注意,接下來纔是重點!!!jquery

表情

舉個栗子:ajax

咱們常常會在網站搜圖片或者看文章,當你不斷下拉的時候,拉到頁面底部,突然!網頁又加載出來一堆圖片和文章,這種狀況,其實就是咱們的AJAX在幹活,是否是內心有點數了?django

第一,AJAX 最大的優勢:編程

  • 在不從新加載整個頁面的狀況下,能夠與服務器交換數據並更新部分網頁內容(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程)。

第二,AJAX工做原理:json

不須要任何瀏覽器插件,但須要用戶容許JavaScript在瀏覽器上執行。後端

img

有人會問,圖片中的「XHR」是什麼東西,別急,咱們慢慢來。

所謂的「XHR」(瀏覽器內置對象」XMLHttpRequest 」),也就是Ajax功能實現所依賴的對象,AJAX就是經過瀏覽器的內置對象XHMHttpResquest來發送異步請求的,異步請求不會妨礙客戶端的任何操做。

  • 異步:

XHR至關因而一個通訊兵,來負責客戶端與服務器之間的通訊傳輸。

舉個形象生動的例子:

要打仗了,前方陣地(客服端)不可能只等着通訊兵(XHR)傳遞消息其餘什麼也不幹吧,因此前方陣地還在幹着本身的事情而後派通訊兵去請求後方指揮部(服務器)的命令,指揮部下達命令指揮,通訊兵再把命令傳到前方陣地,而後前方陣地再執行命令相關的操做(客戶端把數據渲染到頁面),這也就是Ajax的異步原理。

  • 同步:

所謂的同步就是前方陣地和通訊兵一塊兒去向服務器請求數據,直到通訊兵請求到數據,我纔開始渲染頁面,在請求的過程當中頁面一直是白屏等待的。

  • 同步交互:客戶端發出一個請求後,須要等待服務器響應結束後,才能發出第二個請求;
  • 異步交互:客戶端發出一個請求後,無需等待服務器響應結束,就能夠發出第二個請求。

等一下,這個同步異步你們有沒有回想起咱們以前在學習線程進程的時候,也有同步異步。

表情

其實說得簡單點,就是你在燒水,同步就是你啥也不幹就等水開,異步則是水壺一丟去幹別的事了。

1.1 示例

頁面輸入兩個整數,經過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),
]

1.2 AJAX常見應用情景

其實除了上文提到的頁面加載用到的AJAX技術,還有一些常見的例子:

  • 搜索引擎根據用戶輸入的關鍵字,自動提示檢索關鍵字。
  • 註冊時候的用戶名的查重。

當文件框發生了輸入變化時,使用AJAX技術向服務器發送一個請求,而後服務器會把查詢到的結果響應給瀏覽器,最後再把後端返回的結果展現出來。

  • 整個過程當中頁面沒有刷新,只是刷新頁面中的局部位置而已(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程)
  • 當請求發出後,瀏覽器還能夠進行其餘操做,無需等待服務器的響應!

img

具體步驟:

  • 當輸入用戶名後,把光標移動到其餘表單項上時

  • 瀏覽器會使用AJAX技術向服務器發出請求,服務器會查詢名爲lemontree7777777的用戶是否存在

  • 最終服務器返回true表示名爲lemontree7777777的用戶已經存在

  • 瀏覽器在獲得結果後顯示「用戶名已被註冊!」

  • 整個過程當中頁面沒有刷新,只是局部刷新了

  • 在請求發出後,瀏覽器不用等待服務器響應結果就能夠進行其餘操做

1.3 AJAX的優缺點

優勢

  • AJAX使用JavaScript技術向服務器發送異步請求
  • AJAX請求無須刷新整個頁面
  • 由於服務器響應內容再也不是整個頁面,而是頁面中的部份內容,因此AJAX性能高
  • 兩個關鍵點:
    • 局部刷新
    • 異步請求

缺點

  • AJAX幹掉了Back和History功能,即對瀏覽器機制的破壞。

    • 在動態更新頁面的狀況下,用戶沒法回到前一個頁面狀態,由於瀏覽器僅能記憶歷史記錄中的靜態頁面。一個被完整讀入的頁面與一個已經被動態修改過的頁面之間的差異很是微妙;用戶一般會但願單擊後退按鈕可以取消他們的前一次操做,可是在Ajax應用程序中,這將沒法實現。
  • 安全問題技術同時也對IT企業帶來了新的安全威脅。

    • ajax技術就如同對企業數據創建了一個直接通道。
    • 這使得開發者在不經意間會暴露比之前更多的數據和服務器邏輯。
    • ajax的邏輯能夠對客戶端的安全掃描技術隱藏起來,容許黑客從遠端服務器上創建新的攻擊。
    • 還有ajax也難以免一些已知的安全弱點,諸如跨站點腳步攻擊、SQL注入攻擊和基於credentials的安全漏洞等。
  • 對搜索引擎的支持比較弱。若是使用不當,AJAX會增大網絡數據的流量,從而下降整個系統的性能。

這缺點也太長了!!!!你們只須要記住AJAX的局部刷新優勢就行,缺點在優勢面前就顯得...你懂的!

表情包

2. jQuery實現的AJAX(掌握)

最基本的jQuery發送AJAX請求示例:

2.1 html

<!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>

2.2 views.py

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')

2.3 $.ajax參數

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
      }
    })
  })

3. JS實現AJAX(瞭解)

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);
      }
    };
  };

4. AJAX請求如何設置csrf_token

不管是ajax仍是誰,只要是向我Django提交post請求的數據,都必須校驗csrf_token來防僞跨站請求。

表情

那麼如何在個人ajax中弄這個csrf_token呢???

我又不像form表單那樣能夠在表單內部經過一句{% csrf_token %}就搞定了......

4.1 方式一

經過獲取隱藏的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);
  }
})

4.2 方式二

經過獲取返回的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);
  }
})

4.3 方式三

或者用本身寫一個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上傳文件」部分,下篇見:)

表情
相關文章
相關標籤/搜索