ajax(Asynchronous JavaScript + XML) 技術學習
阿新 • • 發佈:2017-06-07
域名 asc nco 通過 zed 你會 echo 服務器端 main
參考文檔:https://developer.mozilla.org/en-US/docs/AJAX
本文進行了大致翻譯。
Ajax 本身本不是一門技術,而是在2005年由Jesse James Garrett首創的描述為一個“新”途徑來應用許多已存在的技術,包括:HTML 或者 XHTML, Cascading Style Sheets, JavaScript, The Document Object Model, XML, XSLT, 和最重要的 XMLHttpRequest object。
當把這些技術結合到ajax模型裏的時候,web app可以快速地,逐漸地更新用戶界面來取代以前的刷新整個瀏覽界面,這使得應用更快和用戶使用體驗更好。
盡管x在ajax裏面代表xml,json由於其更輕和是javascript的一部分等優點而被更多的使用。ajax模型裏面的json和xml都是用來包裝數據信息的。
AJAX 代表 Asynchronous JavaScript And XML. 簡而言之, 他是用 XMLHttpRequestobject 來和服務器交流的方式. 它可以以不同的方式發送和接收信息, 包括 JSON, XML, HTML, 和text文件. AJAX最有吸引力的特性是 "異步", 這意味著它可以在不刷新頁面的情況下同服務器交流,交換數據更新頁面。
ajax的主要兩個主要特性:
什麽是AJAX?
- 不刷新頁面請求數據
- 從服務器獲取數據
Step 1 – 如何請求
為了用javascript請求服務器,我們要實例化一個有必要功能的對象。這是XMLHttpRequest的來源。起初Internet Explorer實現了一個被稱為XMLHTTP的ActiveX對象。 之後,Mozilla, Safari,和其他瀏覽器廠商陸續實現了XMLHttpRequest對象來支持這個方法和類似於Microsof的ActiveX對象功能。同時,Microsoft也實現了XMLHttpRequest。 // Old compatibility code, no longer needed. if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ... httpRequest = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE 6 and older httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } 註意:以上代碼只做解釋作用,只是創建了XMLHttp的實例。可以跳到step 3去看更實用的例子。 請求之後,我們需要接收請求結果。在這個階段,我們需要告訴XMLHttp請求對象來處理響應的JavaScript方法,通過配置他的onreadystatechangeproperty方法,如下:或者httpRequest.onreadystatechange = nameOfTheFunction;
httpRequest.onreadystatechange = function(){
// Process the server response here.
};
在聲明怎麽接受響應之後,我們需要發起請求,通過調用HTTP請求對象的 open() 和 send() 方法,如下:
httpRequest.open(‘GET‘, ‘http://www.example.org/some.file‘, true);
httpRequest.send();
- open() 的第一個參數是HTTP 請求的方法 – GET, POST, HEAD, 或者其他服務器支持的方法。方法名全部大寫是http標準,不然有些瀏覽器(例如:Firefox)可能會不發器請求。 點擊 W3C specs 獲得更多關於http請求方法的信息。
- 第二個參數是要請求的url。從安全方面考慮,默認不能跨域請求url。確保所有頁面在同一個域名下,不然調用open()方法,你會得到 "permission denied” 錯誤。 一個常見的跨域是你網站的域名是 domain.tld,但是嘗試用 www.domain.tld訪問頁面。如果真的想跨域請求,查看 HTTP access control。
- 可選的第三個參數設置這個請求是同步還是異步的。如果是true (默認值), JavaScript 會繼續執行,用戶操作頁面的同時,服務器返回數據。這是 AJAX的A。
"name=value&anothername="+encodeURIComponent(myVar)+"&so=on"
或者其他形式,例如 multipart/form-data,JSON, XML, 等等。
註意如果你想POST數據,你可能要設置請求的MIME type。例如我們把下面代碼放在調用send()之前,來把表單數據當查詢數據發送:
httpRequest.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded‘);
Step 2 – 處理服務器響應
請求的時候,我們已經提供了處理響應的JavaScript方法:httpRequest.onreadystatechange = nameOfTheFunction;
這個方法做什麽?首先,我們需要檢查請求狀態。如果張臺值為XMLHttpRequest.DONE (4),意味著已經接受了所有服務器的響。
if (httpRequest.readyState === XMLHttpRequest.DONE) {
// Everything is good, the response was received.
} else {
// Not ready yet.
}
readyState 全部可能的值,可以在 XMLHTTPRequest.readyState 查看,如下:
- 0 (uninitialized) or (請求未初始化)
- 1 (loading) or (服務器建立連接)
- 2 (loaded) or (請求被接收)
- 3 (interactive) or (執行請求)
- 4 (complete) or (request finished and response is ready請求完成響應到位)
-
Value State Description 0 UNSENT Client has been created. open() not called yet. 1 OPENED open() has been called. 2 HEADERS_RECEIVED send() has been called, and headers and status are available. 3 LOADING Downloading; responseText holds partial data. 4 DONE The operation is complete.
if (httpRequest.status === 200) {
// Perfect!
} else {
// There was a problem with the request.
// For example, the response may have a 404 (Not Found)
// or 500 (Internal Server Error) response code.
}
檢查完響應值後。我們可以隨意處理服務器返回的數據,有兩個選擇獲得這些數據:
- httpRequest.responseText – 返回服務器響應字符串
- httpRequest.responseXML – 返回服務器響應XMLDocument 對象 可以傳遞給JavaScript DOM 方法
Step 3 – 一個簡單的例子
我們把上面的放在一起合成一個簡單的HTTP請求。我們的JavaScript 將請求一個HTML 文檔, test.html, 包含一個字符串 "I‘m a test."然後我們alert()響應內容。這個例子使用普通的JavaScript — 沒有引入jQuery, HTML, XML 和 PHP 文件應該放在同一級目錄下。<button id="ajaxButton" type="button">Make a request</button>
<script>
(function() {
var httpRequest;
document.getElementById("ajaxButton").addEventListener(‘click‘, makeRequest);
function makeRequest() {
httpRequest = new XMLHttpRequest();
if (!httpRequest) {
alert(‘Giving up :( Cannot create an XMLHTTP instance‘);
return false;
}
httpRequest.onreadystatechange = alertContents;
httpRequest.open(‘GET‘, ‘test.html‘);
httpRequest.send();
}
function alertContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert(‘There was a problem with the request.‘);
}
}
}
})();
</script>
在這個例子裏:
- 用戶點擊"Make a request” 按鈕;
- 事件調用 makeRequest() 方法;
- 請求發出,然後 (onreadystatechange)執行傳遞給 alertContents();
- alertContents() 檢查響應是否 OK, 然後 alert() test.html 文件內容。
function alertContents() {
try {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert(‘There was a problem with the request.‘);
}
}
}
catch( e ) {
alert(‘Caught Exception: ‘ + e.description);
}
}
Step 4 – 使用 XML 響應
在前面的例子裏,在獲取到響應之後,我們用request 對象responseText 屬性獲得 test.html 文件內容。現在讓我們嘗試獲取responseXML 屬性。 首先,讓我們創建一個有效的XML文檔,留著待會我們請求。(test.xml)如下:<?xml version="1.0" ?>
<root>
I‘m a test.
</root>
在這個腳本裏,我們只要修改請求行為:
...
onclick="makeRequest(‘test.xml‘)">
...
然後在alertContents()裏,我們需要把 alert(httpRequest.responseText); 換為:
var xmldoc = httpRequest.responseXML;
var root_node = xmldoc.getElementsByTagName(‘root‘).item(0);
alert(root_node.firstChild.data);
這裏獲得了responseXML的XMLDocument,然後用 DOM 方法來獲得包含在XML文檔裏面的內容。你可以在here查看test.xml,在here查看修改後的腳本。
Step 5 – 使用數據返回
最後,讓我們來發送一些數據到服務器,然後獲得響應。我們的JavaScript這次將會請求一個動態頁面,test.php將會獲取我們發送的數據然後返回一個計算後的字符串 - "Hello, [user data]!",然後我們alert()出來。 首先我們加一個文本框到HTML,用戶可以輸入他們的姓名:<label>Your name:
<input type="text" id="ajaxTextbox" />
</label>
<span id="ajaxButton" style="cursor: pointer; text-decoration: underline">
Make a request
</span>
我們也給事件處理方法裏面加一行獲取文本框內容,並把它和服務器端腳本的url一起傳遞給 makeRequest() 方法:
document.getElementById("ajaxButton").onclick = function() {
var userName = document.getElementById("ajaxTextbox").value;
makeRequest(‘test.php‘,userName);
};
我們需要修改makeRequest()方法來接受用戶數據並且傳遞到服務端。我們將把方法從 GET 改為 POST,把我們的數據包裝成參數放到httpRequest.send():
function makeRequest(url, userName) {
...
httpRequest.onreadystatechange = alertContents;
httpRequest.open(‘POST‘, url);
httpRequest.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded‘);
httpRequest.send(‘userName=‘ + encodeURIComponent(userName));
}
如果服務端只返回一個字符串, alertContents() 方法可以和Step 3 一樣。然而,服務端不僅返回計算後的字符串,還返回了原來的用戶名。所以如果我們在輸入框裏面輸入 “Jane”,服務端的返回將會像這樣:
{"userData":"Jane","computedString":"Hi, Jane!"}
要在alertContents()使用數據,我們不能直接alert responseText, 我們必須轉換數據然後 alert computedString屬性:
function alertContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText);
alert(response.computedString);
} else {
alert(‘There was a problem with the request.‘);
}
}
}
test.php 文件如下:
$name = (isset($_POST[‘userName‘])) ? $_POST[‘userName‘] : ‘no name‘;
$computedString = "Hi, " . $name;
$array = [‘userName‘ => $name, ‘computedString‘ => $computedString];
echo json_encode($array);
查看更多DOM方法, 請查看 Mozilla‘s DOM implementation 文檔。ajax(Asynchronous JavaScript + XML) 技術學習