Ajax技術:
Ajax描述了一種主要使用腳本(JS)操縱HTTP的web應用架構,它的主要特色是使用腳本操縱HTTP和web服務器進行數據交換,不會致使頁面重載。Ajax的核心是JS的XMLHttpRequest構造函數,它定義了用腳本操縱HTTP的API。
XMLHttpRequest構造函數:
每new一個XMLHttpRequest構造函數返回的對象都表示一個獨立的請求/響應對,而且這個對象的屬性和方法容許指定請求細節和提取響應數據。須要注意的是當你重用已存在的XMLHttpRequest,這將會終止以前經過該對象掛起的任何請求。
案例:建立一個HTTP API
//該構造函數返回的對象API可以操做HTTP請
var xhr = new XMLHttpRequest();
HTTP API的open()方法:
建立了HTTP API後的下一步就是調用open()方法。這個方法有三個參數,參數一指定HTTP請求的方法,GET、POST、DELETE、HEAD、OPTIONS和PUT都能用。參數二指定了請求的URL,但URL不能是跨域的URL。參數三指定了這個請求是否異步進行,true表示異步,false表示同步。
案例:open()方法的調用
var xhr = new XMLHttpRequest();
var URL = "lookup.php?name=csh&sex=男&ie=utf-8";
xhr.open('GET', URL, true);
onreadystatechange事件:
調用了open()方法後的下一步就是監聽onreadystatechange事件,這個事件主要用於監聽請求返回時的狀態碼(status屬性)和返回數據的狀況(readyState屬性)。當status和readyState屬性符合需求的時候調用回調函數。
readyState屬性:
readyState屬性的值是一個整數,它指定了HTTP請求的狀態。
0表示open()還沒有調用
1表示open()已調用
2表示接收到頭信息
3表示接收到響應主體
4表示響應完成
理論上,每次readyState屬性改變都會觸發readystatechange事件,但實際中當readyState改變爲0或1時可能沒有觸發這個事件。當readyState值改變爲4或服務器的響應完成時,全部的瀏覽器都觸發readystatechange事件。
status屬性:readyState屬性的值是一個整數,它指定了HTTP的狀態碼。
常見的HTTP狀態碼:
HTTP: Status 200 – 服務器成功返回網頁
HTTP: Status 404 – 請求的網頁不存在
HTTP: Status 503 – 服務不可用
案例:監聽onreadystatechange事件
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
//2xx狀態與表示從緩存中直接取出的304能夠看是成功的,IE(非原生的XHR對象)中會將204設置爲1223,opera會在取得204時設置爲0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack(converter[dataType].call(this, xhr.responseText, xhr.responseXML));
}
};
HTTP API的send()方法:
這是HTTP請求的最後一步,調用這個方法把請求發送到服務器。send()有一個可選參數,GET請求的時候爲null,POST請求的時候爲傳給後臺的數據
案例:調用send()方法
var xhr = new XMLHttpRequest();
xhr.send(null);
HTTP API的setRequestHeader()方法:
該方法用於設置HTTP頭信息。而在POST請求時就必需要設置HTTP頭信息的Content-Type屬性,用於告訴服務器發送給它的數據的MIME類型。若是調用setRequestHeader()屢次,新值不會取代以前舊的值,相反,HTTP請求將包含這個頭的多個副本或這個頭將指定多個值。
編碼請求主體:
HTTP POST請求包括一個請求主體,它包含客戶端傳遞給服務器的數據,請求主體除了是簡單的文本字符串以外,還多是複雜的數據。在Ajax應用中,通常狀況下發送到服務器的極可能是一個JS對象(即把數據存放到一個對象裏面,直接把這個對象發送給服務器,也就是說這個對象就是請求主體)。
案例:使用JSON編碼主體來發起HTTP POST請求
function postJSON(url, data, callback){
var request = new XMLHttpRequest();
request.open('POST', url);
//對指定URL發送POST請求
request.onreadystatechange = function (){};
request.setRequestHeader("Content-Type", "application/json");
request.send(JSON.stringify(data));//data對象要轉換爲json類型
};
案例:發送一個GET請求
/**
* GET請求
* @param options 【該參數是一個object】
* {url: 'http://www.plateno.com/index.html, data: {name: 'luke'}, callBack: function(data){}}
*/
function get(options){
var xhr = new XMLHttpRequest(),
async = options.async || true;
try{
//判斷是否傳參數
var data = '', n = 0, a = '';
if (options.data){
data = '?';
for (var name in options.data){
n == 0 ? a = '' : a = '&';
n++;
data += a + name +'='+ encodeURI(options.data[name])
}
}
//判斷是否緩存
var cache = '&' + new Data().getTime();
if (!options.cache){cache = '';}
xhr.open('get', options.url + data + cache, async);
//設置請求數據
xhr.send();
//發送請求
//監聽請求過程
xhr.onreadystatechange = function (){
//2xx狀態與表示從緩存中直接取出的304能夠看是成功的,IE(非原生的XHR對象)中會將204設置爲1223,opera會在取得204時設置爲0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack.call(this, xhr.responseText, xhr.responseXML);
}
}
}catch(e){throw new Error('GET請求失敗');}
}
案例:發送一個POST請求
/**
* POST請求
* @param options 【該參數是一個object】
* {url: 'http://www.plateno.com/index.html', data:{name: 'luke'}, callBack: function(data){}}
*/
function post(options) {
var xhr = new XMLHttpRequest(),
async = options.async || true;
try{
//判斷是否傳參數
var data = '', n = 0, a = '';
if (options.data){
for (var name in options.data){
n == 0 ? a = '' : a = '&';
n++;
data += a + name +'='+ options.data[name]
}
}
xhr.open('post', options.url, async);
//設置請求數據
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");
//設置請求頭
xhr.send(data);
//發送請求
//監聽請求過程
xhr.onreadystatechange = function (){
//2xx狀態與表示從緩存中直接取出的304能夠看是成功的,IE(非原生的XHR對象)中會將204設置爲1223,opera會在取得204時設置爲0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack(converter[dataType].call(this, xhr.responseText, xhr.responseXML));
}
}
}catch(e){throw new Error('POST請求失敗');}
}