ajax 的前世此生

1、ajax基礎

瀏覽器的技術
ajax Asynchronous javascript and xmljavascript

  • xml: 是可擴展標記語言,和html同樣,能夠清楚的表示層級。在ajax剛剛興起的時候,爲了表達數據的結構和層次,數據結構可能是使用xml;
  • 如今都是json,json也能夠表達數據結構;
JSON.parse() // json格式字符串轉對象
    JSON.stringify() // 對象轉JSON格式的字符串
複製代碼
  • 如今的前端都是先後端分離的,即前端負責數據的綁定和維護;
  • 服務端渲染和全局刷新

在好久之前,沒有ajax以前,都是先後端不分離的;先後端不分離是前端寫好html+css結構,而後把html交給後端,而後利用服務端技術從服務器的數據庫中把數據查出來,而後綁定到頁面中,而後把綁定好數據的頁面直接返回給瀏覽器,就是說瀏覽器拿的就是綁定好數據的頁面html(服務端渲染SSR(Server-Side-Rendering));css

可是這麼幹有一個問題,若是我這個頁面中只有一部份內容是動態綁定的,若是我須要看到這部份內容,就須要刷新整個頁面從新獲取才行,由於綁定數據只有在服務器上才能進行。這種體驗很很差,這種刷新整個頁面獲取數據的方式稱爲全局刷新;html

  • 先後端分離

後來ajax誕生了,ajax能夠直接從服務器獲取數據而不用刷新整個頁面;發送一個ajax請求,等到請求結束後把數據經過前端手段把數據綁定到頁面中(動態建立dom+appendChild或者字符串拼接+innerHTML)。這種用ajax渲染數據的方式是局部刷新的。前端

  • ajax 的實例是能夠向服務器發送請求的;

使用ajax

  1. 建立一個ajax實例對象
let xhr = new XMLHttpRequest();
複製代碼
  1. 能夠經過XMLHttpRequest原型上的open方法打開一個路徑
xhr.open('get', 'https://www.easy-mock.com/mock/xxx95ef4e9dd1a28c/example/myfirstmock', true);
複製代碼

open方法的參數:
http-method: GET POST
url
async: true 表示異步,false表示同步java

  1. 監聽ajax實例的onreadystatechange事件,當ajax發送請求時,會觸發這個事件行爲
xhr.onreadystatechange = function () {
   若是ajax是異步執行的,這個函數會執行三次,三次的readyState分別爲x
   console.log(xhr.readyState); 2  3  4

   爲了肯定拿到數據,咱們不只判斷xhr.readyState 判斷,還須要根據xhr.status來判斷,xhr使用的就是http status,表示當前請求的狀態;

  if (xhr.readyState === 4 && /^2\d{2}/.test(xhr.status)) {
     xhr.readyState 爲4表示ajax請求完成,xhr.status 是一個以2開頭的三位數,表示請求成功,因此能夠在獲取服務端返回的數據
  }
};
複製代碼

4.發送請求jquery

xhr.send(); // send方法還能夠傳遞參數
複製代碼

xhr.readyState 表示當前ajax實例對象的所處的狀態
0: 建立了一個ajax實例對象
1: 已經調用open方法,打開了路徑
2: 客戶端已經接收到服務端的信息(若是須要獲取頭信息中某些內容,能夠在readyState爲2時獲取就能夠)
3: 客戶端正在接收響應主體的數據
4: 客戶端已經所有接收服務端的數據ajax

2、ajax的請求方式

let xhr = new XMLHttpRequest();
    xhr.open('get', 'aside.json', true);

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && /^2\d{2}/.test(xhr.status)) {
        console.log(xhr.responseText);
        }
    };

    xhr.send(JSON.stringify({username: 'mabin', pwd: '1233456'}));
複製代碼
  • xhr.open() 方法的第一個參數用於指定http-method,即http的請求方式:

通常接口的請求方式由服務端提供,並且會在接口文檔中說明數據庫

常見的請求方式:

=> GET: 通常用於從服務端獲取數據,可是也能夠向服務器傳遞少許的數據;

get請求方式的特色

1.向服務器傳遞數據的方式:經過向接口末尾添加問號傳參的方式傳遞,如: aside.json?name=mabinpwd=123456
2.因爲瀏覽器的url地址是有長度限制的,IE的url通常不超過2k,谷歌的通常在8k,超過的部分會自動被截掉,因此get請求傳遞的數據很小
3.參數直接暴露在url中,安全性低;
4.get請求容易產生緩存,爲了防止緩存,通常在url末尾拼接一個隨機數或者時間戳,由於瀏覽器發現url變化了,就會從新請求而不是使用以前已經緩存的數據;json

=> POST 通常用於把數據傳遞給服務器或者傳遞大量的數據時

1.post 把須要傳遞給服務器的數據放在請求體中傳遞給服務器
2.因爲post數據放在請求體中,大小沒有限制
3.post 傳遞數據時把數據放在請求體中的,相對於get而言比較安全
4.post 請求不會默認走緩存後端

其餘請求方式

+DELETE: 刪除數據
+HEAD: 獲取響應頭,不須要響應體
+PUT: 修改某些內容
+OPTIONS: 查詢服務器的支持的http請求方式
+TRACE: 回顯服務器收到的請求,通常用於測試
+....

3、ajax的同步和異步

  • js是單線程的:每次只能執行一個任務
  • 瀏覽器是多線程的,能夠同時執行多個任務;
let data = null;

    let xhr = new XMLHttpRequest();

    xhr.open('get', 'aside.json', true);

    xhr.onreadystatechange = function () {
      console.log(xhr.readyState); // false 時只輸出 4
      console.log(xhr.readyState); // true 時輸出2 3 4
      data = xhr.responseText;
    };

    xhr.send();

    function bindHTML(data) {
      // 綁定html的方法
    }
複製代碼

爲何會有異步的ajax?

  • 若是頁面中有5個請求
// 1. 1s
    // 2. 2s
    // 3. 3s
    // 4. 4s
    // 5. 5s
複製代碼
  • 若是使用同步的,同步任務都是阻塞的,上一個執行不完下一個不能開始,若是這些接口沒有必然關係,用戶須要15s才能看到,這個用戶體驗很很差。
  • 若是使用異步的,第一個發出後隨即就開始第二個,而後第三個,由於異步不是阻塞的,後面的不用等待前面的完成(這樣子看起來很像同時發送了5個請求),這樣一來用時5s就能夠了

因此通常狀況下ajax使用異步的;

  • 可是使用異步的也有一個問題,若是這5個接口是互相依賴的,好比第二個依賴第一個返回的數據,第三個依賴第二個返回的數據這種狀況使用異步,順序是沒法保證的,由於異步任務是誰先到達執行條件誰先執行;

4、jq的ajax

使用原生的ajax把用戶名和密碼使用post的請求發方式發送到aside.json

<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <section>
      <label for="uName">用戶名:</label>
      <input type="text" id="uName">
    </section>
    <section>
       <label for="pwd">密碼:</label>
       <input type="text" id="pwd">
    </section>
    <section>
       <button id="submit">登陸</button>
    </section>

    <script src="js/jquery-3.2.1.js"></script>
    <script src="js/4-jq的ajax.js"></script>
    </body>
    </html>
複製代碼

原生js代碼:

  • 獲取元素
let uName = document.getElementById('uName');
    let pwd = document.getElementById('pwd');

    let uNameValue = uName.value;
    let pwdValue = pwd.value;
    let btn = document.getElementById('submit');
複製代碼
  • 原生js
btn.onclick = function () {
    let xhr = new XMLHttpRequest();
    xhr.open('post', 'aside.json', true);
    xhr.onreadystatechange = function () {
       if (xhr.readyState === 4 && xhr.status === 200) {
       console.log('oh yeach');
       }
    };
    // 注意post請求只能發送字符串類型的數據,一邊狀況下會使用json格式的字符串
    xhr.send(JSON.stringify({
       username: uNameValue,
       pwd: pwdValue
     }));
    };
複製代碼

使用jq的ajax

$.ajax({
       url: 'aside.json',
       type: 'post',
       dataType: 'json',
       cache: false,
       async: true,
       data: {
            username: uNameValue,
            pwd: pwdValue
        },
        error(err) {
             console.log(err)
        },
        success (data) {
            console.log(data)
        }
    });
複製代碼

參數詳解 url: 請求路徑 type: 請求方式 dataType: 數據類型json async: true 默認異步 cache: false 禁用緩存 error: 請求失敗時執行的回調,參數是具體的報錯信息 success: 請求成功執行的回調,參數是服務端返回的數據

相關文章
相關標籤/搜索