【Ajax教科書】原生Ajax開發步驟總結

一、瞭解Ajax

1.1 什麼是Ajax?

AJAX = 異步 JavaScript 和 XML(Asynchronous JavaScript and XML)。是一種用於創建快速動態網頁的技術。通過在後臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。而傳統的網頁(不使用 AJAX)如果需要更新內容,必需重載整個頁面。

簡短地說,在不重載整個網頁的情況下,AJAX 通過後臺加載數據,並在網頁上進行顯示。

二、Ajax的工作原理

image-20200509135507495

Ajax的原理簡單來說通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然後用javascript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數據。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所瞭解。

XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是javascript可以及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。

AJAX是基於現有的Internet標準,並且聯合使用它們:

  • XMLHttpRequest 對象 (異步的與服務器交換數據)
  • JavaScript/DOM (信息顯示/交互)
  • CSS (給數據定義樣式)
  • XML (作爲轉換數據的格式)、JSON

三、Ajax get/post實例

3.1 Ajax開發步驟

  1. 建XMLHTTPRequest對象
  2. 設置onreadystatechange回調函數(回調函數中的參數data是用來跨域獲取數據的)
  3. open() 打開連接
  4. send() 發送請求

注意:回調函數中的data參數,在進行跨域的時候,我們需要獲取對應接口的數據並對數據進行相應的處理,那麼就可以通過接口所提供的回調函數通過傳參來獲取數據。

3.2 get實例

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Ajax.Get</title>
</head>
<body>
<script type="text/javascript">
    //1.創建異步XMLHttpRequest對象
    function createXMLHttpRequest() {
        var xmlHttp;
        try {
            xmlHttp = new XMLHttpRequest();
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
        return xmlHttp;
    }

    var xhr = createXMLHttpRequest();
    //2.設置回調函數
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var responseText = xhr.responseText;
            var jsObject = eval("(" + responseText + ")");
            console.log(jsObject.flag);
            console.log(jsObject.msg);
        }
    };
    //3.打開連接
    xhr.open("get", "${pageContext.request.contextPath}/test?username=ziph&password=123456&id=" + Math.random(), true);
    //4.發送參數
    xhr.send();
</script>
</body>
</html>

3.3 post實例

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Ajax.post</title>
</head>
<body>
<script type="text/javascript">
    //1.創建異步XMLHttpRequest對象
    function createXMLHttpRequest() {
        var xmlHttp;
        try {
            xmlHttp = new XMLHttpRequest();
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {

                }
            }
        }
        return xmlHttp;
    }

    var xhr = createXMLHttpRequest();
    //2.設置回調函數
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var responseText = xhr.responseText;
            var jsObject = eval("(" + responseText + ")");
            console.log(jsObject.flag);
            console.log(jsObject.msg);
        }
    }
    //3.打開連接
    xhr.open("post", "${pageContext.request.contextPath}/test", true);
    //4.設置請求頭
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    //5.發送參數
    xhr.send("username=ziph&password=123456");
</script>
</body>
</html>

3.4 實例Servlet測試

package com.mylifes1110.java.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet(name = "TestServlet", value = "/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username : " + username + " , password : " + password);
        boolean flag = true;
        String msg = "賬戶可用";
        if ("root".equals(username) || "zhangsan".equals(username)) {
            flag = false;
            msg = "賬戶已經被註冊";
        } else {
            msg = "賬戶可用";
            flag = true;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("flag", flag);
        map.put("msg", msg);
        response.setContentType("text/html;charset=utf-8");
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(map);
        response.getWriter().write(jsonStr);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

四、分佈式解析Ajax步驟

這是之間簡單的羅列以下,講解步驟中會詳細講到!

屬性 描述
onreadystatechange 每次狀態改變所觸發事件的事件處理程序
responseText 從服務器進程返回數據的字符串形式
responseXML 從服務器進程返回的DOM兼容的文檔數據對象
status 從服務器返回的數字代碼,比如常見的404(未找到)和200(已就緒)
status Text 伴隨狀態碼的字符串信息
readyState 對象狀態值(XMLHttpRequest對象的處理狀態)

4.1 創建XMLHttpRequest對象

XMLHttpRequest對象是AJAX的基礎。所有現代瀏覽器均支持 XMLHttpRequest 對象(IE5 和 IE6 使用 ActiveXObject)。XMLHttpRequest 用於在後臺與服務器交互數據。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。

所有現代瀏覽器(IE7+、Firefox、Chrome、Safari 以及 Opera)均內建 XMLHttpRequest 對象。創建 XMLHttpRequest 對象的語法:

var xmlhttp = new XMLHttpRequest(); 

Internet Explorer 使用 ActiveX 對象:

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");

Internet Explorer 老版本則也是使用 ActiveX 對象:

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

所以,綜上所述,我們爲了應對所有的現代瀏覽器,包括 IE5 和 IE6,請檢查瀏覽器是否支持 XMLHttpRequest 對象。如果支持,則創建 XMLHttpRequest 對象。如果不支持,則創建 ActiveXObject (封裝方法):

function createXMLHttpRequest() {
        var xmlHttp;
        try {
            xmlHttp = new XMLHttpRequest();
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
        return xmlHttp;
    }

4.2 onreadystatechange回調函數(監聽狀態)

當請求被髮送到服務器時,我們需要執行一些基於響應的任務。每當 readyState 改變時,就會觸發 onreadystatechange 事件。readyState 屬性存有 XMLHttpRequest 的狀態信息。

下面是 XMLHttpRequest 對象的三個重要的屬性:

屬性 描述
onreadystatechange 存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。
readyState 存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。0: 請求未初始化、1: 服務器連接已建立、2: 請求已接收、3: 請求處理中、4: 請求已完成,且響應已就緒
status 200:“OK”;404:未找到頁面

在 onreadystatechange 事件中,我們規定當服務器響應已做好被處理的準備時所執行的任務。

注意: onreadystatechange 事件被觸發 4 次, 五個狀態(0 - 4),對應着 readyState 的每個變化。

注意: 回調函數中的data參數,在進行跨域的時候,我們需要獲取對應接口的數據並對數據進行相應的處理,那麼就可以通過接口所提供的回調函數通過傳參來獲取數據。

當 readyState 等於 4 且狀態爲 200 時,表示響應已就緒:

xhr.onreadystatechange = function(data){
        if (xhr.readyState == 4 && xhr.status == 200) {
            //這裏寫響應成功後的代碼
            var responseText = xhr.responseText;
            var jsObject = eval("(" + responseText + ")");
            console.log(jsObject.flag);
            console.log(jsObject.msg);
        }
    };

readyState的狀態的詳細解釋

XMLHttpRequest對象的處理狀態

  • 0(未初始化):對象已建立,但是尚未初始化(尚未調用open方法)
  • 1(初始化):對象開始發送請求,對象已建立,尚未調用send方法
  • 2(發送數據):對象的請求發送完成,send方法已調用,但是當前的狀態及http頭未知
  • 3(數據傳輸):對象開始讀取服務器的響應,已接收部分數據,因爲響應及http頭不全,這時通過responseBody和responseText獲取部分數據會出現錯誤,
  • 4(完成):對象讀取服務器響應完成,數據接收完畢,此時可以通過通過responseXml和responseText獲取完整的迴應數據

4.3 XMLHttpRequest請求

如需將請求發送到服務器,我們使用 XMLHttpRequest 對象的 open() 和 send() 方法:

xmlhttp.open("GET","servlet",true);
xmlhttp.send();
方法 描述
open(method,url,async) 規定請求的類型、URL 以及是否異步處理請求。method:請求的類型;GET 或 POSTurl:文件在服務器上的位置async:true(異步)或 false(同步)
send(string) 將請求發送到服務器。string:僅用於 POST 請求

method-請求方式

GET 還是 POST?

與 POST 相比,GET 更簡單也更快,並且在大部分情況下都能用。

然而,在以下情況中,請使用 POST 請求:

  • 不使用緩存文件(更新服務器上的文件或數據庫)
  • 向服務器發送大量數據(POST 沒有數據量限制)
  • 發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠

GET 請求

一個簡單的 GET 請求:

xmlhttp.open("GET","/servlet",true);
xmlhttp.send();

在上面的例子中,您可能得到的是緩存的結果。

爲了避免這種情況,請向 URL 添加一個唯一的 ID:

xmlhttp.open("GET","/xxx/xxx/xxx/servlet??id=" + Math.random(),true);
xmlhttp.send();

如果希望通過 GET 方法發送信息,請向 URL 添加信息:

xmlhttp.open("GET","/xxx/xxx/xxx/servlet?username=ziph&password=123456",true);
xmlhttp.send();

POST 請求

一個簡單 POST 請求

xmlhttp.open("POST","/xxx/xxx/xxx/servlet",true);
xmlhttp.send();

如果需要像 HTML 表單那樣 POST 數據,請使用 setRequestHeader() 來添加 HTTP 頭。然後在 send() 方法中規定您希望發送的數據:

xmlhttp.open("POST","/xxx/xxx/xxx/servlet",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=utf-8");
xmlhttp.send("username=ziph&password=123456");
方法 描述
setRequestHeader(header,value) 向請求添加 HTTP 頭。header: 規定頭的名稱 value: 規定頭的值

url - 服務器地址

open() 方法的 url 參數是服務器上資源的地址:

xmlhttp.open("GET","servlet",true);

異步 - True 或 False

AJAX 指的是異步 JavaScript 和 XML(Asynchronous JavaScript and XML)。
XMLHttpRequest 對象如果要用於 Ajax 的話,其 open() 方法的 async 參數必須設置爲 true:

xmlhttp.open("GET","/xxx/xxx/xxx/servlet",true);

對於 web 開發人員來說,發送異步請求是一個巨大的進步。很多在服務器執行的任務都相當費時。Ajax 出現之前,這可能會引起應用程序掛起或停止。

通過 Ajax,JavaScript 無需等待服務器的響應,而是:

  • 在等待服務器響應時執行其他腳本
  • 當響應就緒後對響應進行處理

Async=true

當使用 async=true 時,請規定在響應處於 onreadystatechange 事件中的就緒狀態時執行的函數:

xmlhttp.onreadystatechange = function(data)
{
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
		//成功後的執行代碼
    }
}
xmlhttp.open("GET","/xxx/xxx/xxx/servlet",true);
xmlhttp.send();

Async=false

如需使用 async=false,請將 open() 方法中的第三個參數改爲 false:

我們不推薦使用 async=false,但是對於一些小型的請求,也是可以的。

請記住,JavaScript 會等到服務器響應就緒才繼續執行。如果服務器繁忙或緩慢,應用程序會掛起或停止。

**注意:**當您使用 async=false 時,請不要編寫 onreadystatechange 函數。把代碼放到 send() 語句後面即可:

xmlhttp.open("GET","/xxx/xxx/xxx/servlet",false);
xmlhttp.send();
//執行代碼

4.4 XMLHttpRequest響應

服務器響應

如需獲得來自服務器的響應,請使用 XMLHttpRequest 對象的 responseText 或 responseXML 屬性。

屬性 描述
responseText 獲得字符串形式的響應數據。
responseXML 獲得 XML 形式的響應數據。

responseText 屬性

如果來自服務器的響應並非 XML,請使用 responseText 屬性。

responseText 屬性返回字符串形式的響應,因此可以這樣使用:

document.getElementById("myDiv").innerHTML = xmlhttp.responseText;

responseXML 屬性

如果來自服務器的響應是 XML,而且需要作爲 XML 對象進行解析,請使用 responseXML 屬性:

xmlDoc = xmlhttp.responseXML;
txt = "";
x = xmlDoc.getElementsByTagName("ARTIST");
for (i = 0;i < x.length;i++)
{
    txt = txt + x[i].childNodes[0].nodeValue + "<br>";
}
document.getElementById("myDiv").innerHTML=txt;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章