關於ajax的名字 ajax 的全稱是Asynchronous JavaScript and XML,其中,Asynchronous 是非同步的意思,它有別於傳統web開發中採用的同步的方式。 關於同步和非同步 非同步傳輸是面向字元的傳輸,它的單位是字元;而同步傳輸是面向比特的傳輸,它的單位是楨,它傳輸的 ...
關於ajax的名字
ajax 的全稱是Asynchronous JavaScript and XML,其中,Asynchronous 是非同步的意思,它有別於傳統web開發中採用的同步的方式。
關於同步和非同步
非同步傳輸是面向字元的傳輸,它的單位是字元;而同步傳輸是面向比特的傳輸,它的單位是楨,它傳輸的時候要求接受方和發送方的時鐘是保持一致的。
具體來說,非同步傳輸是將比特分成小組來進行傳送。一般每個小組是一個8位字元,在每個小組的頭部和尾部都有一個開始位和一個停止位,它在傳送過程中接收方和發送方的時鐘不要求一致,也就是說,發送方可以在任何時刻發送這些小組,而接收方並不知道它什麼時候到達。一個最明顯的例子就是電腦鍵盤和主機的通信,按下一個鍵的同時向主機發送一個8比特位的ASCII代 碼,鍵盤可以在任何時刻發送代碼,這取決於用戶的輸入速度,內部的硬體必須能夠在任何時刻接收一個鍵入的字元。這是一個典型的非同步傳輸過程。非同步傳輸存在 一個潛在的問題,即接收方並不知道數據會在什麼時候到達。在它檢測到數據並做出響應之前,第一個比特已經過去了。這就像有人出乎意料地從後面走上來跟你說 話,而你沒來得及反應過來,漏掉了最前面的幾個詞。因此,每次非同步傳輸的信息都以一個起始位開頭,它通知接收方數據已經到達了,這就給了接收方響應、接收 和緩存數據比特的時間;在傳輸結束時,一個停止位表示該次傳輸信息的終止。按照慣例,空閑(沒有傳送數據)的線路實際攜帶著一個代表二進位1的信號。步傳輸的開始位使信號變成0,其他的比特位使信號隨傳輸的數據信息而變化。最後,停止位使信號重新變回1,該信號一直保持到下一個開始位到達。例如在鍵盤上數字“1”,按照8比特位的擴展ASCII編碼,將發送“00110001”,同時需要在8比特位的前面加一個起始位,後面一個停止位。
同步傳輸的比特分組要大得多。它不是獨立地發送每個字元,每個字元都有自己的開始位和停止位,而是把它們組合起來一起發送。我們將這些組合稱為數據幀,或簡稱為幀。
數據幀的第一部分包含一組同步字元,它是一個獨特的比特組合,類似於前面提到的起始位,用於通知接收方一個幀已經到達,但它同時還能確保接收方的採樣速度和比特的到達速度保持一致,使收發雙方進入同步。
幀的最後一部分是一個幀結束標記。與同步字元一樣,它也是一個獨特的比特串,類似於前面提到的停止位,用於表示在下一幀開始之前沒有別的即將到達的數據了。
同步傳輸通常要比非同步傳輸快速得多。接收方不必對每個字元進行開始和停止的操作。一旦檢測到幀同步字元,它就在接下來的數據到達時接收它們。另外,同步傳輸的開銷也比較少。例如,一個典型的幀可能有500位元組(即4000比特)的數據,其中可能只包含100比特的開銷。這時,增加的比特位使傳輸的比特總數增加2.5%,這與非同步傳輸中25 %的增值要小得多。隨著數據幀中實際數據比特位的增加,開銷比特所占的百分比將相應地減少。但是,數據比特位越長,緩存數據所需要的緩衝區也越大,這就限制了一個幀的大小。另外,幀越大,它占據傳輸媒體的連續時間也越長。在極端的情況下,這將導致其他用戶等得太久。
瞭解了同步和非同步的概念之後,大家應該對ajax為什麼可以提升用戶體驗應該比較清晰了,它是利用非同步請求方式的。打個比方,如果現在你家裡所在的小區因 某種情況而面臨停水,現在有關部門公佈了兩種方案,一是完全停水8個小時,在這8個小時內完全停水,8個小時後恢復正常。二是不完全停水10 個小時,在這10個小時內水沒有完全斷,只是流量比原來小了很多,在10個小時後恢復正常流量,那麼,如果是你你會選擇哪種方式呢?顯然是後者。
ajax所包含的技術
大家都知道ajax並非一種新的技術,而是幾種原有技術的結合體。它由下列技術組合而成。
1.使用CSS和XHTML來表示。
2. 使用DOM模型來交互和動態顯示。
3.使用XMLHttpRequest來和伺服器進行非同步通信。
4.使用javascript來綁定和調用。
在上面幾中技術中,除了XmlHttpRequest對象以外,其它所有的技術都是基於web標準並且已經得到了廣泛使用的,XMLHttpRequest雖然目前還沒有被W3C所採納,但是它已經是一個事實的標準,因為目前幾乎所有的主流瀏覽器都支持它。
ajax原理和XmlHttpRequest對象
Ajax的原理簡單來說通過XmlHttpRequest對象來向伺服器發非同步請求,從伺服器獲得數據,然後用javascript來操作DOM而更新頁面。這其中最關鍵的一步就是從伺服器獲得請求數據。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所瞭解。
XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持非同步請求的技術。簡單的說,也就是javascript可以及時向伺服器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。
所以我們先從XMLHttpRequest講起,來看看它的工作原理。
首先,我們先來看看XMLHttpRequest這個對象的屬性。
它的屬性有:
onreadystatechange 每次狀態改變所觸發事件的事件處理程式。
responseText 從伺服器進程返回數據的字元串形式。
responseXML 從伺服器進程返回的DOM相容的文檔數據對象。
status 從伺服器返回的數字代碼,比如常見的404(未找到)和200(已就緒)
status Text 伴隨狀態碼的字元串信息
readyState 對象狀態值
0 (未初始化) 對象已建立,但是尚未初始化(尚未調用open方法)
1 (初始化) 對象已建立,尚未調用send方法
2 (發送數據) send方法已調用,但是當前的狀態及http頭未知
3 (數據傳送中) 已接收部分數據,因為響應及http頭不全,這時通過responseBody和responseText獲取部分數據會出現錯誤,
4 (完成) 數據接收完畢,此時可以通過通過responseXml和responseText獲取完整的回應數據
但是,由於各瀏覽器之間存在差異,所以創建一個XMLHttpRequest對象可能需要不同的方法。這個差異主要體現在IE和其它瀏覽器之間。下麵是一個比較標準的創建XMLHttpRequest對象的方法。
function CreateXmlHttp() {
//非IE瀏覽器創建XmlHttpRequest對象
if (window.XMLHttpRequest) {
xmlhttp = new XmlHttpRequest();
}
//IE瀏覽器創建XmlHttpRequest對象
if (window.ActiveXObject) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
try {
xmlhttp = new ActiveXObject("msxml2.XMLHTTP");
}
catch (ex) { }
}
}
}
function Ustbwuyi() {
var data = document.getElementById("username").value;
CreateXmlHttp();
if (!xmlhttp) {
alert("創建xmlhttp對象異常!");
return false;
}
xmlhttp.open("POST", url, false);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
document.getElementById("user1").innerHTML = "數據正在載入...";
if (xmlhttp.status == 200) {
document.write(xmlhttp.responseText);
}
}
}
xmlhttp.send();
}
如上所示,函數首先檢查XMLHttpRequest的整體狀態並且保證它已經完成(readyStatus=4),即數據已經發送完畢。然後根據伺服器的設定詢問請求狀態,如果一切已經就緒(status=200),那麼就執行下麵需要的操作。
對於XmlHttpRequest的兩個方法,open和send,其中open方法指定了:
a、向伺服器提交數據的類型,即post還是get。
b、請求的url地址和傳遞的參數。
c、傳輸方式,false為同步,true為非同步。預設為true。如果是非同步通信方式(true),客戶機就不等待伺服器的響應;如果是同步方式(false),客戶機就要等到伺服器返回消息後才去執行其他操作。我們需要根據實際需要來指定同步方式,在某些頁面中,可能會發出多個請求,甚至是有組織有計劃有隊形大規模的高強度的request,而後一個是會覆蓋前一個的,這個時候當然要指定同步方式。
Send方法用來發送請求。
知道了XMLHttpRequest的工作流程,我們可以看出,XMLHttpRequest是完全用來向伺服器發出一個請求的,它的作用也局限於此,但它的作用是整個ajax實現的關鍵,因為ajax無非是兩個過程,發出請求和響應請求。並且它完全是一種客戶端的技術。而XMLHttpRequest正是處理了伺服器端和客戶端通信的問題所以才會如此的重要。
現在,我們對ajax的原理大概可以有一個瞭解了。我們可以把伺服器端看成一個數據介面,它返回的是一個純文本流,當然,這個文本流可以是XML格式,可以是Html,可以是Javascript代碼,也可以只是一個字元串。這時候,XMLHttpRequest向伺服器端請求這個頁面,伺服器端將文本的結果寫入頁面,這和普通的web開發流程是一樣的,不同的是,客戶端在非同步獲取這個結果後,不是直接顯示在頁面,而是先由javascript來處理,然後再顯示在頁面。至於現在流行的很多ajax控制項,比如magicajax等,可以返回DataSet等其它數據類型,只是將這個過程封裝了的結果,本質上他們並沒有什麼太大的區別。
jquery中的ajax方法參數總是記不住,這裡記錄一下。
1.url:
要求為String類型的參數,(預設為當前頁地址)發送請求的地址。
2.type:
要求為String類型的參數,請求方式(post或get)預設為get。註意其他http請求方法,例如put和delete也可以使用,但僅部分瀏覽器支持。
3.timeout:
要求為Number類型的參數,設置請求超時時間(毫秒)。此設置將覆蓋$.ajaxSetup()方法的全局設置。
4.async:
要求為Boolean類型的參數,預設設置為true,所有請求均為非同步請求。如果需要發送同步請求,請將此選項設置為false。註意,同步請求將鎖住瀏覽器,用戶其他操作必須等待請求完成才可以執行。
5.cache:
要求為Boolean類型的參數,預設為true(當dataType為script時,預設為false),設置為false將不會從瀏覽器緩存中載入請求信息。
6.data:
要求為Object或String類型的參數,發送到伺服器的數據。如果已經不是字元串,將自動轉換為字元串格式。get請求中將附加在url後。防止這種自動轉換,可以查看 processData選項。對象必須為key/value格式,例如{foo1:"bar1",foo2:"bar2"}轉換為&foo1=bar1&foo2=bar2。如果是數組,JQuery將自動為不同值對應同一個名稱。例如{foo:["bar1","bar2"]}轉換為&foo=bar1&foo=bar2。
7.dataType:
要求為String類型的參數,預期伺服器返回的數據類型。如果不指定,JQuery將自動根據http包mime信息返回responseXML或responseText,並作為回調函數參數傳遞。可用的類型如下:
xml:返回XML文檔,可用JQuery處理。
html:返回純文本HTML信息;包含的script標簽會在插入DOM時執行。
script:返回純文本JavaScript代碼。不會自動緩存結果。除非設置了cache參數。註意在遠程請求時(不在同一個域下),所有post請求都將轉為get請求。
json:返回JSON數據。
jsonp:JSONP格式。使用SONP形式調用函數時,例如myurl?callback=?,JQuery將自動替換後一個“?”為正確的函數名,以執行回調函數。
text:返回純文本字元串。
8.beforeSend:
要求為Function類型的參數,發送請求前可以修改XMLHttpRequest對象的函數,例如添加自定義HTTP頭。在beforeSend中如果返回false可以取消本次ajax請求。XMLHttpRequest對象是惟一的參數。
function(XMLHttpRequest){
this; //調用本次ajax請求時傳遞的options參數
}
9.complete:
要求為Function類型的參數,請求完成後調用的回調函數(請求成功或失敗時均調用)。參數:XMLHttpRequest對象和一個描述成功請求類型的字元串。
function(XMLHttpRequest, textStatus){
this; //調用本次ajax請求時傳遞的options參數
}
10.success:要求為Function類型的參數,請求成功後調用的回調函數,有兩個參數。
(1)由伺服器返回,並根據dataType參數進行處理後的數據。
(2)描述狀態的字元串。
function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //調用本次ajax請求時傳遞的options參數
}
11.error:
要求為Function類型的參數,請求失敗時被調用的函數。該函數有3個參數,即XMLHttpRequest對象、錯誤信息、捕獲的錯誤對象(可選)。ajax事件函數如下:
function(XMLHttpRequest, textStatus, errorThrown){
//通常情況下textStatus和errorThrown只有其中一個包含信息
this; //調用本次ajax請求時傳遞的options參數
}
12.contentType:
要求為String類型的參數,當發送信息至伺服器時,內容編碼類型預設為"application/x-www-form-urlencoded"。該預設值適合大多數應用場合。
13.dataFilter:
要求為Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
function(data, type){
//返回處理後的數據
return data;
}
14.dataFilter:
要求為Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
function(data, type){
//返回處理後的數據
return data;
}
15.global:
要求為Boolean類型的參數,預設為true。表示是否觸發全局ajax事件。設置為false將不會觸發全局ajax事件,ajaxStart或ajaxStop可用於控制各種ajax事件。
16.ifModified:
要求為Boolean類型的參數,預設為false。僅在伺服器數據改變時獲取新數據。伺服器數據改變判斷的依據是Last-Modified頭信息。預設值是false,即忽略頭信息。
17.jsonp:
要求為String類型的參數,在一個jsonp請求中重寫回調函數的名字。該值用來替代在"callback=?"這種GET或POST請求中URL參數里的"callback"部分,例如{jsonp:'onJsonPLoad'}會導致將"onJsonPLoad=?"傳給伺服器。
18.username:
要求為String類型的參數,用於響應HTTP訪問認證請求的用戶名。
19.password:
要求為String類型的參數,用於響應HTTP訪問認證請求的密碼。
20.processData:
要求為Boolean類型的參數,預設為true。預設情況下,發送的數據將被轉換為對象(從技術角度來講並非字元串)以配合預設內容類型"application/x-www-form-urlencoded"。如果要發送DOM樹信息或者其他不希望轉換的信息,請設置為false。
21.scriptCharset:
要求為String類型的參數,只有當請求時dataType為"jsonp"或者"script",並且type是GET時才會用於強制修改字元集(charset)。通常在本地和遠程的內容編碼不同時使用。
1 $(function(){ 2 $('#send').click(function(){ 3 $.ajax({ 4 type: "GET", 5 url: "test.json", 6 data: {username:$("#username").val(), content:$("#content").val()}, 7 dataType: "json", 8 success: function(data){ 9 $('#resText').empty(); //清空resText裡面的所有內容 10 var html = ''; 11 $.each(data, function(commentIndex, comment){ 12 html += '<div class="comment"><h6>' + comment['username'] 13 + ':</h6><p class="para"' + comment['content'] 14 + '</p></div>'; 15 }); 16 $('#resText').html(html); 17 } 18 }); 19 }); 20 });
ajax的優點
Ajax的給我們帶來的好處大家基本上都深有體會,在這裡我只簡單的講幾點:
1、最大的一點是頁面無刷新,在頁面內與伺服器通信,給用戶的體驗非常好。
2、使用非同步方式與伺服器通信,不需要打斷用戶的操作,具有更加迅速的響應能力。
3、可以把以前一些伺服器負擔的工作轉嫁到客戶端,利用客戶端閑置的能力來處理,減輕伺服器和帶寬的負擔,節約空間和寬頻租用成本。並且減輕伺服器的負擔,ajax的原則是“按需取數據”,可以最大程度的減少冗餘請求,和響應對伺服器造成的負擔。
4、基於標準化的並被廣泛支持的技術,不需要下載插件或者小程式。
ajax的缺點
下麵我著重講一講ajax的缺陷,因為平時我們大多註意的都是ajax給我們所帶來的好處諸如用戶體驗的提升。而對ajax所帶來的缺陷有所忽視。
下麵所闡述的ajax的缺陷都是它先天所產生的。
1、ajax幹掉了back按鈕,即對瀏覽器後退機制的破壞。後退按鈕是一個標準的web站點的重要功能,但是它沒法和js進行很好的合作。這是ajax所帶來的一個比較嚴重的問題,因為用戶往往是希望能夠通過後退來取消前一次操作的。那麼對於這個問題有沒有辦法?答案是肯定的,用過Gmail的知道,Gmail下麵採用的ajax技術解決了這個問題,在Gmail下麵是可以後退的,但是,它也並不能改變ajax的機制,它只是採用的一個比較笨但是有效的辦法,即用戶單擊後退按鈕訪問歷史記錄時,通過創建或使用一個隱藏的IFRAME來重現頁面上的變更。(例如,當用戶在Google Maps中單擊後退時,它在一個隱藏的IFRAME中進行搜索,然後將搜索結果反映到Ajax元素上,以便將應用程式狀態恢復到當時的狀態。)
但是,雖然說這個問題是可以解決的,但是它所帶來的開發成本是非常高的,和ajax框架所要求的快速開發是相背離的。這是ajax所帶來的一個非常嚴重的問題。
2、安全問題
技術同時也對IT企業帶來了新的安全威脅,ajax技術就如同對企業數據建立了一個直接通道。這使得開發者在不經意間會暴露比以前更多的數據和伺服器邏輯。ajax的邏輯可以對客戶端的安全掃描技術隱藏起來,允許黑客從遠端伺服器上建立新的攻擊。還有ajax也難以避免一些已知的安全弱點,諸如跨站點腳步攻擊、SQL註入攻擊和基於credentials的安全漏洞等。
3、對搜索引擎的支持比較弱。
4、破壞了程式的異常機制。至少從目前看來,像ajax.dll,ajaxpro.dll這些ajax框架是會破壞程式的異常機制的。關於這個問題,我曾經在開發過程中遇到過,但是查了一下網上幾乎沒有相關的介紹。後來我自己做了一次試驗,分別採用ajax和傳統的form提交的模式來刪除一條數據……給我們的調試帶來了很大的困難。
5、另外,像其他方面的一些問題,比如說違背了url和資源定位的初衷。例如,我給你一個url地址,如果採用了ajax技術,也許你在該url地址下麵看到的和我在這個url地址下看到的內容是不同的。這個和資源定位的初衷是相背離的。
6、一些手持設備(如手機、PDA等)現在還不能很好的支持ajax,比如說我們在手機的瀏覽器上打開采用ajax技術的網站時,它目前是不支持的,當然,這個問題和我們沒太多關係。
ajax的幾種框架
目前我們採用的比較多的ajax框架主要有ajax.dll,ajaxpro.dll,magicajax.dll 以及微軟的atlas框架。Ajax.dll和Ajaxpro.dll這兩個框架差別不大,而magicajax.dll只是封裝得更厲害一些,比如說它可以直接返回DataSet數據集,前面我們已經說過,ajax返回的都是字元串,magicajax只是對它進行了封裝而已。但是它的這個特點可以給我們帶來很大的方便,比如說我們的頁面有一個列表,而列表的數據是不斷變化的,那麼我們可以採用magicajax來處理,操作很簡單,添加magicajax之後,將要更新的列表控制項放在magicajax的控制項之內,然後在pageload裡面定義更新間隔的時間就ok了,atlas的原理和magicajax差不多。但是,需要註意的一個問題是,這幾種框架都只支持IE,沒有進行瀏覽器相容方面的處理,用反編譯工具察看他們的代碼就可以知道。
除了這幾種框架之外,我們平時用到的比較多的方式是自己創建xmlHttpRequest對象,這種方式和前面的幾種框架相比更具有靈活性。另外,在這裡還提一下aspnet2.0自帶的非同步回調介面,它和ajax一樣也可以實現局部的無刷新,但它的實現實際上也是基於xmlhttprequest對象的,另外也是只支持IE,當然這是微軟的一個競爭策略。
ajax示例
驗證用戶名是否註冊。
採用兩種方式
1 ajax.dll
2 自己寫xmlhttprequest對象
此文要感謝:http://www.cnblogs.com/ustbwuyi/archive/2007/02/08/645061.html#2215165