AJAX解析請求得到的資料(多種格式)

2020-07-16 10:05:11
在 JavaScript 中,一般將格式設定為 XML、HTML、JSON 或其他純文字格式。具體使用哪種響應格式,可以參考下面幾條原則。
  • 如果向頁面中新增大塊資料,選擇 HTML 格式會比較方便。
  • 如果需要共同作業開發,且專案龐雜,選擇 XML 格式會更通用。
  • 如果要檢索複雜的資料,且結構複雜,那麼選擇 JSON 格式更加輕便。

獲取 XML 資料

XMLHttpRequest 物件通過 responseText、responseBody、responseStream 或 responseXML 屬性獲取響應資訊,說明如下表所示,它們都是唯讀屬性。

XMLHttpRequest 物件響應資訊屬性
響應資訊 說明
responseBody 將響應資訊正文以 Unsigned Byte 陣列形式返回
responseStream  以 ADO Stream 物件的形式返回響應資訊
responseText 將響應資訊作為字串返回
responseXML 將響應資訊格式化為 XML 文件格式返回

範例1

在伺服器端建立一個簡單的 XML 文件。
<?xml version="1.0" encoding="utf-8"?>
<the>XML 資料</the>
然後,在用戶端進行如下請求。createXHR() 方法在建立 XMLHttpRequest 物件中講解過。
<input name="submit" type="button" id="submit" value="向伺服器發出請求" />
<script>
    window.onload = function () {  //頁面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //範例化XMLHttpRequest物件
            xhr.open("GET", "server.xml", true);  //建立連線,要求非同步響應
            xhr.onreadystatechange = function () {  //係結響應狀態事件監聽函數
                if (xhr.readyState == 4) {  //監聽readyState狀態
                    if (xhr.state == 200 || xhr.status == 0) {  //監聽HTTP狀態碼
                        var info = xhr.responseXML;
                        console.log(info.getElementsByTagName("the")[0].firstChild.data);  //返回元資訊字串“XML 資料”
                    }
                }
            }
            xhr.send();  //傳送請求
        }
    }
</script>
在上面程式碼中,使用 XML DOM 的 getElementsByTagName() 方法獲取 the 節點,然後再定位第一個 the 節點的子節點內容。此時如果繼續使用 responseText 屬性來讀取資料,則會返回 XML 原始碼字串。

範例2

以範例 1 為例,使用伺服器端指令碼生成 XML 結構資料。
<?php
    header('Content-Type: text/html;');
    echo '<?xml version="1.0" encoding="utf-8"?><the>XML 資料</the>';  //輸出XML
?>

獲取 HTML 字串

設計響應資訊為 HTML 字串,然後使用 innerHTML 把獲取的字串插入到網頁中。

範例

在伺服器端設計響應資訊為 HTML 結構程式碼。
<table border="1" width="100%">
    <tr><td>RegExp.exec()</td><td>通用的匹配模式</td></tr>
    <tr><td>RegExp.test()</td><td>檢測一個字串是否匹配某個模式</td></tr>
</table>
然後在用戶端可以這樣接收響應資訊。
<input name="submit" type="button" id="submit" value="向伺服器發出請求" />
<script>
    window.onload = function () {  //頁面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //範例化XMLHttpRequest物件
            xhr.open("GET", "server.xml", true);  //建立連線,要求非同步響應
            xhr.onreadystatechange = function () {  //係結響應狀態事件監聽函數
                if (xhr.readyState == 4) {  //監聽readyState狀態
                    if (xhr.state == 200 || xhr.status == 0) {  //監聽HTTP狀態碼
                        var o = document.getElementById("grid");
                        o.innerHTML = xhr.responseText;  //直接插入到頁面中
                    }
                }
            }
            xhr.send();  //傳送請求
        }
    }
</script>

在某些情況下,HTML 字串可能為用戶端解析響應資訊節省了一些 JavaScript 指令碼,但是也帶來了一些問題。
  • 響應資訊中包含大量無用的字元,響應資料會變得很臃腫。因為 HTML 標記不含有資訊,完全可以把它們放置在用戶端,由 JavaScript 指令碼負責生成。
  • 響應資訊中包含的 HTML 結構無法有效利用,對於 JavaScript 指令碼來說,它們僅僅是一堆字串。同時結構和資訊混合在一起,也不符合標準化設計原則。

獲取 JavaScript 指令碼

設計相應為 JavaScript 程式碼,與 JSON 資料不同,它是可執行的命令或指令碼。

範例

在伺服器端請求檔案中包含下面一個函數。
function () {
    var d = new Date();
    return d.toString();
}
然後在用戶端執行下面的請求。
<input name="submit" type="button" id="submit" value="向伺服器發出請求" />
<script>
    window.onload = function () {  //頁面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //範例化XMLHttpRequest物件
            xhr.open("GET", "server.xml", true);  //建立連線,要求非同步響應
            xhr.onreadystatechange = function () {  //係結響應狀態事件監聽函數
                if (xhr.readyState == 4) {  //監聽readyState狀態
                    if (xhr.state == 200 || xhr.status == 0) {  //監聽HTTP狀態碼
                        var info = xhr.responseText;
                        var o = eval("(" + info + ")" + "()");  //用eval()把字串轉換為指令碼
                        console.log(o);  //返回用戶端當前資訊
                    }
                }
            }
            xhr.send();  //傳送請求
        }
    }
</script>
使用 eval() 方法時,在字串前後附加兩個小括號:一個是包含函數結構體的,一個是表示呼叫函數的。不建議直接使用 JavaScript 程式碼作為響應格式,因為它不能傳遞更豐富的資訊,同時 JavaScript 指令碼極易引發安全隱患。

獲取 JSON 資料

使用 responseText 可以獲取 JSON 格式的字串,然後使用 eval() 方法將其解析為本地 JavaScript 指令碼,再從該資料物件中讀取資訊。

範例

在伺服器端請求檔案中包含下面 JSON 資料。
{ user : "css8", pass : "123456", email : "[email protected]" }
然後在用戶端執行下面的請求。把返回 JSON 字串轉換為物件,然後讀取屬性值。
<input name="submit" type="button" id="submit" value="向伺服器發出請求" />
<script>
    window.onload = function () {  //頁面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //範例化XMLHttpRequest物件
            xhr.open("GET", "server.xml", true);  //建立連線,要求非同步響應
            xhr.onreadystatechange = function () {  //係結響應狀態事件監聽函數
                if (xhr.readyState == 4) {  //監聽readyState狀態
                    if (xhr.state == 200 || xhr.status == 0) {  //監聽HTTP狀態碼
                        var info = xhr.responseText;
                        var o = eval("(" + info + ")");  //呼叫eval()把字串轉換為本地指令碼
                        console.log(info);  //顯示JSON物件字串
                        console.log(o.user);  //讀取物件屬性值,返回字串“css8”
                    }
                }
            }
            xhr.send();  //傳送請求
        }
    }
</script>
eval() 方法在解析 JSON 字串時存在安全隱患。如果 JSON 字串中包含惡意程式碼,在呼叫回撥函數時可能會被執行。解決方法:先對 JSON 字串進行過濾,遮蔽掉敏感或惡意程式碼。不過,確信所響應的 JSON 字串是安全的,沒有被人惡意攻擊,那麼可以使用 eval() 方法解析 JSON 字串。

獲取純文字

對於簡短的資訊,可以使用純文字格式進行響應。但是純文字資訊在傳遞過程中容易丟失,且沒有辦法檢測資訊的完整性。

範例

伺服器端響應資訊為字串“true”,則可以在用戶端這樣設計。
var xhr = createXHR();  //範例化XMLHttpRequest物件
xhr.open("GET", "server.txt", true);  //建立連線,要求非同步響應
xhr.nreadystatechange = function () {  //係結響應狀態事件監聽函數
    if (xhr.readyState == 4) {  //監聽readyState函數
        if (xhr.status == 200 || xhr.status == 0) {  //監聽HTTP狀態碼
            var info = xhr.responseText;
            if (info == "true") console.log("文字資訊傳輸完整");  //檢測資訊是否完整
            else console.log("文字資訊可能存在丟失");
        }
    }
}
xhr.send();  //傳送請求