一篇博客搞懂 Ajax 是什麼(Ajax原來這麼簡單)

古之立大事者,不唯有超世之才,亦必有堅忍不拔之志——蘇軾javascript

寫在前面

在接觸 Ajax 以前,咱們一直都是同步交互,所謂同步交互,就是指發送一個請求,須要等待返回,而後纔可以發送下一個請求。同步相互至關於排隊,輪到下一個的狀況會由於前一個而有所不一樣。html

Ajax 能夠幫助咱們實現異步交互,所謂的異步交互,就是指發送一個請求,不須要等待返回,隨時能夠在發送下一個請求。同步交互與異步交互的區別在於同步交互須要等待結果,而異步交互不須要等待。java

Ajax 概述

Ajax 是什麼

Ajax 是 Asynchronous Javavascript XML 的縮寫,被譯爲異步 JavaScript 和 XML 。Ajax 自己並非一個新技術,而是一個在 2005 年被 Jesse James Garrett 提出的新術語,用來描述一種使用現有技術集合的 「新」方法。shell

當使用 Ajax 模型,HTML 頁面可以快速地將數據逐步更新顯示在用戶界面上,不須要重載(刷新)整個頁面。這使得 HMTL 頁面可以快速的對用戶的操做進行反饋。瀏覽器

儘管 Ajax 中的 「X」 表明 XML ,但因爲 JSON 的許多優點,目前 JSON 的使用比 XML 更加廣泛。 JSON 和 XML 都被用於在 Ajax 模型中封裝數據。安全

異步交互的優點

異步交互相比同步交互的優點主要具備如下幾點:服務器

  • 用戶操做無須像同步交互必須等待結果。
  • 異步交互只需與服務器端交換必要的數據內容,而不是將全部數據所有更新。
  • 異步交互對帶寬形成的壓力相比同步交互更小。
  • 經過 Ajax 實現異步交互不須要任何第三方插件,只要瀏覽器支持 JavaScript 語言便可實現。

異步交互的劣勢

異步交互相比同步交互並非優點,它也存在一些問題:markdown

  • 異步交互破壞了瀏覽器原有的前進和後退機制。
  • 若是後面邏輯的執行依靠前面邏輯執行的結果的話,異步交互可能會形成問題。
  • Ajax 實現異步交互對搜索引擎支持較弱。
  • Ajax 實現異步交互會引發一些 Web 安全問題,例如 SQL 注入攻擊、跨站點腳本攻擊等問題。

Ajax 涉及的技術

Ajax 只是爲實現異步交互的手段,不是一種技術,而是多種技術的整合。其中包括如下幾種技術:app

  • HTML 頁面
  • CSS
  • JavaScript 腳本語言
  • Document Object Model (DOM)
  • XML
  • XMLHttpRequest 對象

上述技術中,XMLHttpRequest 對象是實現 Ajax 異步交互的核心。異步

Ajax 的核心對象

實現 Ajax 異步交互的核心就是 XMLHttpRequest 對象,該對象爲客戶端提供了在客戶端和服務器之間傳輸數據的功能。

XMLHttpRequest 對象提供了一個經過 URL 來獲取數據的簡單方式,而且不會是整個頁面刷新。這使得網頁只更新一部分頁面而不會打擾到用戶。

XMLHttpRequest 對象最初有微軟設計,隨後被 Mozilla 、 Apple 和 Google 採納。現在,該對象已經被 W3C 組織標準化。經過該對象,能夠很容易地獲得一個 URL 上的資源數據。儘管名字裏 XML, 但 XMLHttpRequest 對象能夠獲得全部類型的數據資源,並不侷限於 XML 格式的數據。

實現 Ajax 異步交互

實現 Ajax 的執行步驟

實現 Ajax 異步交互須要服務器邏輯進行配合,而做爲客戶端的 HTML 頁面須要完成如下步驟:

  1. 建立 Ajax 的核心對象 XMLHttpRequest 對象。
  2. 經過 XMLHttpRequest 對象的 open() 方法與服務端創建鏈接。
  3. 構建請求所需的數據內容,並經過 XMLHttpRequest 對象的 send() 方法發送給服務器端
  4. 經過 XMLHttpRequest 對象提供的 onreadystatechange 事件監聽服務器端你的通訊狀態
  5. 接受並處理服務端向客戶端響應的數據結果
  6. 將處理結果更新到 HTML 頁面中

建立 XMLHttpRequest 對象。

XMLHttpRequest 對象已經被 W3C 組成進行標準化,可是仍是存在 IE 瀏覽器的兼容問題,不過比較好的就是微軟已經放棄了自家的 IE 瀏覽器,也就說咱們幾乎已經不用考慮瀏覽器兼容問題了。

XMLHttpRequest() 構造函數用於初始化一個 XMLHttpRequest 實例對象。在調用下列任何其餘方法以前,必須先調用該構造函數,或經過其餘方式,獲得一個實例對象。

示例代碼以下所示

var request = new XMLHttpRequest();
複製代碼

與服務器創建鏈接

經過 XMLHttpRequest 對象的 open() 方法與服務器創建鏈接,該方法的語法結構以下所示:

xhrReq.open(method, url, [async][, user][, password]);
複製代碼

參數說明:

  • method: 表示當前的請求方式

    常見的爲 GET 和 POST

  • url: 表示當前請求的服務器端地址鏈接

  • async: 一個可選的布爾參數,表示是否異步執行操做,默認爲true

  • user: 可選的用戶名用於認證用途;默認爲null

  • password: 可選的密碼用於認證用途,默認爲null

給服務端發送數據

經過 XMLHttpRequest 對象的 send() 方法,將客戶端頁面的數據發送給服務端,該方法的語法結構以下所示:

xhrReq.send([body])
複製代碼

參數說明:

  • body: 在 XHR 請求中要發送的數據體,若是不傳遞數據則爲 null

綁定 onreadystatechange 事件

onreadystatechange 事件用於監聽服務器端的通訊狀態,該事件監聽的依靠是 XMLHttpRequest.readyState 屬性,該屬性返回一個 XMLHttpRequest 代理當前所處的狀態,只要當前屬性值被改變,就觸發 onreadystatechange 事件。該屬性有 5 種狀態,以下表所示:

狀態 描述
0 UNSENT 代理被建立,但還沒有調用 open() 方法。
1 OPENED open() 方法已經被調用。
2 HEADERS_RECEIVED send() 方法已經被調用,而且頭部和狀態已經可得到。
3 LOADING 正在響應
4 DONE 響應已完畢

XMLHttpRequest.responseText屬性用於接收服務器端的響應結果。

示例代碼以下所示:

這裏隨便找了個 RUL 做爲測試

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ajax的實現步驟</title>
</head>

<body>
<button id="btn">按鈕</button>
  <script> var btn = document.getElementById('btn') btn.addEventListener('click', function () { // 1. 實例化 XMLHttpRequest 對象 var xhrReq = new XMLHttpRequest(); // 2. 經過 .open() 方法創建鏈接 xhrReq.open('GET', 'https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState'); // 3. 經過 .send() 方法向服務器端發送數據 xhrReq.send(null); // 4. 綁定 onreadystatechange 事件 xhrReq.onreadystatechange = function () { /* .readyState 屬性表示當前狀態 值 描述 0 代理被建立,但還沒有調用 open() 方法。 1 open() 方法已經被調用。 2 send() 方法已經被調用,而且頭部和狀態已經可得到。 3 正在響應 4 響應已完畢 */ if (xhrReq.readyState === 4) { console.log(xhrReq.responseText); } } }) </script>
</body>
   
</html>
複製代碼

執行結果以下圖所示:

image-20201114093558270

實現 Ajax 的異步交互的問題

onreadystatechange 事件的綁定位置

onreadystatechange 事件的綁定位置不一樣,XMLHttpRequest.readyState 屬性的結果也不同,上面的代碼中XMLHttpRequest.readyState 屬性的執行結果爲

2
3
4
複製代碼

咱們若是改一下調用位置的話,其執行結果會怎麼樣呢?

示例代碼以下所示

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>實現 Ajax 異步交互</title>
</head>

<body>
  <button id="btn">按鈕</button>
  <script> var btn = document.getElementById('btn') btn.addEventListener('click', function () { var xhrReq = new XMLHttpRequest(); xhrReq.onreadystatechange = function () { /* .readyState 屬性表示當前狀態 值 描述 0 代理被建立,但還沒有調用 open() 方法。 1 open() 方法已經被調用。 2 send() 方法已經被調用,而且頭部和狀態已經可得到。 3 正在響應 4 響應已完畢 */ console.log(xhrReq.readyState); } xhrReq.open('GET', 'https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState'); xhrReq.send(null); }) </script>
</body>

</html>
複製代碼

執行結果以下圖所示

從執行結果能夠看出,Ajax 的實現步驟並非只有那一種。

可是爲何沒有狀態 0 呢?這是由於咱們在綁定這個以前必須完成對象的初始化,而狀態 0 表示對象未初始化,因此不能獲得狀態 0。

根據這些狀態的不一樣咱們能夠完成不一樣的操做。

send() 方法的問題

若是當前的請求方式爲 GET 的話, send() 方法中只能傳遞 null 值,若是想要添加請求數據的話須要將請求添加地址鏈接中。

發送數據的格式以下所示

name=value
複製代碼

若是多個數據的話須要使用 & 分隔。

請求方式

GET 請求方式

Ajax 異步交互中使用 GET 請求方式的話,須要注意一下兩個問題:

  1. 將構建的請求數據添加到 open() 方法中的 URL 地址中。
  2. 發送請求數據中的 send() 方法中參數設置爲 null 值。

POST 請求方式

Ajax 異步交互中若是使用的是 POST 請求的話,須要注意下面兩個問題

  1. 調用 send() 方法以前, open() 方法以後,須要經過 XMLHttpRequest 對象的 setRequestHeader() 方法設置請求頭信息。

    setRequestHeader() 語法結構以下所示

    xhrReq.setRequestHeader(header, value);
    複製代碼

    參數說明:

    • header: 屬性的名稱。
    • value: 屬性的值。
  2. 經過 XMLHttpRequest 對象的 send() 方法發送請求數據。

示例代碼以下所示

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>POST請求方式</title>
</head>

<body>
  <button id="btn">按鈕</button>
  <script> var btn = document.getElementById('btn') btn.addEventListener('click', function () { var xhrReq = new XMLHttpRequest(); xhrReq.open('POST', 'https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState'); /* 在open方法以後 send 以前設置請求頭 xhrReq.setRequestHeader(header, value); - header: 屬性的名稱。 - value: 屬性的值。 */ xhrReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhrReq.send('user=is_sweet&pwd=123456'); }) </script>
</body>

</html>
複製代碼

執行結果以下所示

寫在最後

本篇博客介紹了 Ajax 的的概念和 Ajax 怎麼用,掌握了 Ajax 就掌握了 異步交互的基礎了。

相關文章
相關標籤/搜索