1抑钟、ajax技術(shù)的背景
不可否認(rèn),ajax技術(shù)的流行得益于google的大力推廣,正是由于google earth副瀑、google suggest以及gmail等對(duì)ajax技術(shù)的廣泛應(yīng)用民傻,催生了ajax的流行胰默。而這也讓微軟感到無比的尷尬,因?yàn)樵缭?7年漓踢,微軟便已經(jīng)發(fā)明了ajax中的關(guān)鍵技術(shù)牵署,并且在99年IE5推出之時(shí),它便開始支持XmlHttpRequest對(duì)象喧半,并且微軟之前已經(jīng)開始在它的一些產(chǎn)品中應(yīng)用ajax奴迅,比如說MSDN網(wǎng)站菜單中的一些應(yīng)用。遺憾的是薯酝,不知道出于什么想法半沽,當(dāng)時(shí)微軟發(fā)明了ajax的核心技術(shù)之后爽柒,并沒有看到它的潛力而加以發(fā)展和推廣,而是將它擱置起來者填。對(duì)于這一點(diǎn)來說浩村,我個(gè)人是覺得非常奇怪的,因?yàn)橐晕④浀馁Y源和它的戰(zhàn)略眼光來說占哟,應(yīng)該不會(huì)看不到ajax技術(shù)的前景心墅,唯一的解釋也許就是因?yàn)楫?dāng)時(shí)它的主要競(jìng)爭(zhēng)對(duì)手Netscape的消失反而使它變得麻痹和遲鈍,畢竟巨人也有打盹的時(shí)候榨乎,比如IBM曾經(jīng)在對(duì)微軟戰(zhàn)略上的失誤怎燥。正是這一次的失誤,成就了它現(xiàn)在的競(jìng)爭(zhēng)對(duì)手google在ajax方面的領(lǐng)先地位蜜暑,而事實(shí)上google目前在ajax技術(shù)方面的領(lǐng)先是微軟所無法達(dá)到的铐姚,這一點(diǎn)在后面我講述ajax缺陷的時(shí)候也會(huì)提到。現(xiàn)在微軟也意識(shí)到了這個(gè)問題肛捍,因此它也開始在ajax領(lǐng)域奮起直追隐绵,比如說推出它自己的ajax框架atlas,并且在.NET2.0也提供了一個(gè)用來實(shí)現(xiàn)異步回調(diào)的接口拙毫,即ICallBack接口依许。那么微軟為什么對(duì)自己在ajax方面的落后如此緊張呢?現(xiàn)在就讓我們來分析一下ajax技術(shù)后面隱藏的深刻意義缀蹄。
2峭跳、ajax技術(shù)的意義
我們?cè)谄綍r(shí)的開發(fā)中都多多少少的接觸或者應(yīng)用到了ajax,談到ajax技術(shù)的意義缺前,我們關(guān)注得最多的毫無疑問是提升用戶的體驗(yàn)蛀醉。但是,如果我們結(jié)合將來電腦和互聯(lián)網(wǎng)的發(fā)展趨勢(shì)诡延,我們會(huì)發(fā)現(xiàn)ajax技術(shù)在某些方面正好代表了這種趨勢(shì)滞欠。為什么這樣說呢?我們知道肆良,自從電腦出現(xiàn)以來筛璧,一直是桌面軟件占據(jù)著絕對(duì)主導(dǎo)的地位,但是互聯(lián)網(wǎng)的出現(xiàn)和成功使這一切開始發(fā)生著微妙的變化惹恃。相當(dāng)一部分的人都相信夭谤,遲早有一天,數(shù)據(jù)和電腦軟件將會(huì)從桌面轉(zhuǎn)移到互聯(lián)網(wǎng)巫糙。也就是說朗儒,將來的電腦有可能拋棄笨重的硬盤,而直接從互聯(lián)網(wǎng)來獲取數(shù)據(jù)和服務(wù),我記得我念大學(xué)的時(shí)候醉锄,有位教授給我們上課的時(shí)候乏悄,曾經(jīng)設(shè)想過這樣一種情景,也許在將來的電腦桌面上恳不,沒有任何多余的軟件和程序檩小,而僅僅只有一個(gè)IE,雖然現(xiàn)在看起來我們距離這一天還很遙遠(yuǎn)烟勋,并且這其中還有很多的問題需要解決规求,但是我覺得這個(gè)并非夢(mèng)想,而是遲早將實(shí)現(xiàn)的現(xiàn)實(shí)卵惦。那么阻肿,這其中的主要問題就是互聯(lián)網(wǎng)的連接不穩(wěn)定,誰也不愿意看著自己的電腦從服務(wù)器一點(diǎn)一滴的下載數(shù)據(jù)沮尿,那么丛塌,ajax是不是解決了這個(gè)問題呢,說實(shí)話蛹找,與其說ajax解決了這個(gè)問題姨伤,倒不如它只是掩蓋了這個(gè)問題,它只是在服務(wù)器和客戶端之間充當(dāng)了一個(gè)緩沖器庸疾,讓用戶誤以為服務(wù)沒有中斷。精確的說当编,ajax并不能提高從服務(wù)器端下載數(shù)據(jù)的速度届慈,而只是使這個(gè)等待不那么令人沮喪。但是正是這一點(diǎn)就足以產(chǎn)生巨大的影響和震動(dòng)忿偷,它實(shí)際上也對(duì)桌面軟件產(chǎn)生了巨大的沖擊金顿。這一點(diǎn)我用一個(gè)例子來說明,我們可以比較一下Outlook Express和Gmail鲤桥,前者是典型的桌面軟件揍拆,后者是ajax所實(shí)現(xiàn)的B/S模式,實(shí)際上后者目前已經(jīng)在慢慢取代前者了茶凳,Gmail在收發(fā)郵件的時(shí)候已經(jīng)和Outlook Express的功能幾乎沒有差別了嫂拴,而且它不需要安裝客戶端程序。這就是為什么微軟對(duì)ajax所帶來的沖擊有著如此的恐懼心理贮喧,并且在它前不久所進(jìn)行的調(diào)查之中筒狠,將google看做他們未來十年內(nèi)的主要競(jìng)爭(zhēng)對(duì)手的主要原因之一。當(dāng)然箱沦,這種變化也并不會(huì)將桌面軟件全部淘汰辩恼,現(xiàn)有的瀏覽器還沒有一個(gè)能像PhotoShop等桌面程序那樣處理復(fù)雜的圖像。但是我們也不能忽視它帶來的影響和沖擊。
3灶伊、關(guān)于ajax的名字
ajax的全稱是Asynchronous JavaScript and XML疆前,其中,Asynchronous是異步的意思聘萨,它有別于傳統(tǒng)web開發(fā)中采用的同步的方式峡继。
4、關(guān)于同步和異步
異步傳輸是面向字符的傳輸匈挖,它的單位是字符碾牌;而同步傳輸是面向比特的傳輸,它的單位是楨儡循,它傳輸?shù)臅r(shí)候要求接受方和發(fā)送方的時(shí)鐘是保持一致的舶吗。
具體來說,異步傳輸是將比特分成小組來進(jìn)行傳送择膝。一般每個(gè)小組是一個(gè)8位字符誓琼,在每個(gè)小組的頭部和尾部都有一個(gè)開始位和一個(gè)停止位,它在傳送過程中接收方和發(fā)送方的時(shí)鐘不要求一致肴捉,也就是說腹侣,發(fā)送方可以在任何時(shí)刻發(fā)送這些小組,而接收方并不知道它什么時(shí)候到達(dá)齿穗。一個(gè)最明顯的例子就是計(jì)算機(jī)鍵盤和主機(jī)的通信傲隶,按下一個(gè)鍵的同時(shí)向主機(jī)發(fā)送一個(gè)8比特位的ASCII代碼,鍵盤可以在任何時(shí)刻發(fā)送代碼窃页,這取決于用戶的輸入速度跺株,內(nèi)部的硬件必須能夠在任何時(shí)刻接收一個(gè)鍵入的字符。這是一個(gè)典型的異步傳輸過程脖卖。異步傳輸存在一個(gè)潛在的問題乒省,即接收方并不知道數(shù)據(jù)會(huì)在什么時(shí)候到達(dá)。在它檢測(cè)到數(shù)據(jù)并做出響應(yīng)之前畦木,第一個(gè)比特已經(jīng)過去了袖扛。這就像有人出乎意料地從后面走上來跟你說話,而你沒來得及反應(yīng)過來十籍,漏掉了最前面的幾個(gè)詞蛆封。因此,每次異步傳輸?shù)男畔⒍家砸粋€(gè)起始位開頭妓雾,它通知接收方數(shù)據(jù)已經(jīng)到達(dá)了娶吞,這就給了接收方響應(yīng)、接收和緩存數(shù)據(jù)比特的時(shí)間械姻;在傳輸結(jié)束時(shí)妒蛇,一個(gè)停止位表示該次傳輸信息的終止机断。按照慣例,空閑(沒有傳送數(shù)據(jù))的線路實(shí)際攜帶著一個(gè)代表二進(jìn)制1的信號(hào)绣夺。步傳輸?shù)拈_始位使信號(hào)變成0吏奸,其他的比特位使信號(hào)隨傳輸?shù)臄?shù)據(jù)信息而變化。最后陶耍,停止位使信號(hào)重新變回1奋蔚,該信號(hào)一直保持到下一個(gè)開始位到達(dá)。例如在鍵盤上數(shù)字“1”烈钞,按照8比特位的擴(kuò)展ASCII編碼泊碑,將發(fā)送“00110001”,同時(shí)需要在8比特位的前面加一個(gè)起始位毯欣,后面一個(gè)停止位馒过。
同步傳輸?shù)谋忍胤纸M要大得多。它不是獨(dú)立地發(fā)送每個(gè)字符酗钞,每個(gè)字符都有自己的開始位和停止位腹忽,而是把它們組合起來一起發(fā)送。我們將這些組合稱為數(shù)據(jù)幀砚作,或簡(jiǎn)稱為幀窘奏。
數(shù)據(jù)幀的第一部分包含一組同步字符,它是一個(gè)獨(dú)特的比特組合葫录,類似于前面提到的起始位着裹,用于通知接收方一個(gè)幀已經(jīng)到達(dá),但它同時(shí)還能確保接收方的采樣速度和比特的到達(dá)速度保持一致压昼,使收發(fā)雙方進(jìn)入同步求冷。
幀的最后一部分是一個(gè)幀結(jié)束標(biāo)記。與同步字符一樣窍霞,它也是一個(gè)獨(dú)特的比特串,類似于前面提到的停止位拯坟,用于表示在下一幀開始之前沒有別的即將到達(dá)的數(shù)據(jù)了但金。
同步傳輸通常要比異步傳輸快速得多。接收方不必對(duì)每個(gè)字符進(jìn)行開始和停止的操作郁季。一旦檢測(cè)到幀同步字符冷溃,它就在接下來的數(shù)據(jù)到達(dá)時(shí)接收它們。另外梦裂,同步傳輸?shù)拈_銷也比較少似枕。例如,一個(gè)典型的幀可能有500字節(jié)(即4000比特)的數(shù)據(jù)年柠,其中可能只包含100比特的開銷凿歼。這時(shí),增加的比特位使傳輸?shù)谋忍乜倲?shù)增加2.5%,這與異步傳輸中25 %的增值要小得多答憔。隨著數(shù)據(jù)幀中實(shí)際數(shù)據(jù)比特位的增加味赃,開銷比特所占的百分比將相應(yīng)地減少。但是虐拓,數(shù)據(jù)比特位越長(zhǎng)心俗,緩存數(shù)據(jù)所需要的緩沖區(qū)也越大,這就限制了一個(gè)幀的大小蓉驹。另外城榛,幀越大,它占據(jù)傳輸媒體的連續(xù)時(shí)間也越長(zhǎng)态兴。在極端的情況下狠持,這將導(dǎo)致其他用戶等得太久。
了解了同步和異步的概念之后诗茎,大家應(yīng)該對(duì)ajax為什么可以提升用戶體驗(yàn)應(yīng)該比較清晰了工坊,它是利用異步請(qǐng)求方式的。打個(gè)比方敢订,如果現(xiàn)在你家里所在的小區(qū)因某種情況而面臨停水王污,現(xiàn)在有關(guān)部門公布了兩種方案,一是完全停水8個(gè)小時(shí)楚午,在這8個(gè)小時(shí)內(nèi)完全停水昭齐,8個(gè)小時(shí)后恢復(fù)正常。二是不完全停水10個(gè)小時(shí)矾柜,在這10個(gè)小時(shí)內(nèi)水沒有完全斷阱驾,只是流量比原來小了很多,在10個(gè)小時(shí)后恢復(fù)正常流量怪蔑,那么里覆,如果是你你會(huì)選擇哪種方式呢?顯然是后者缆瓣。
5喧枷、ajax所包含的技術(shù)
大家都知道ajax并非一種新的技術(shù)界斜,而是幾種原有技術(shù)的結(jié)合體币绩。它由下列技術(shù)組合而成。
1.使用CSS和XHTML來表示峦树。
2.使用DOM模型來交互和動(dòng)態(tài)顯示渡冻。
3.使用XMLHttpRequest來和服務(wù)器進(jìn)行異步通信戚扳。
4.使用javascript來綁定和調(diào)用。
在上面幾中技術(shù)中族吻,除了XmlHttpRequest對(duì)象以外帽借,其它所有的技術(shù)都是基于web標(biāo)準(zhǔn)并且已經(jīng)得到了廣泛使用的珠增,XMLHttpRequest雖然目前還沒有被W3C所采納,但是它已經(jīng)是一個(gè)事實(shí)的標(biāo)準(zhǔn)宜雀,因?yàn)槟壳皫缀跛械闹髁鳛g覽器都支持它切平。
6、ajax原理和XmlHttpRequest對(duì)象
XMLHttpRequest 是 AJAX 的基礎(chǔ)辐董。
XMLHttpRequest 對(duì)象:
所有現(xiàn)代瀏覽器均支持 XMLHttpRequest 對(duì)象(IE5 和 IE6 使用 ActiveXObject)悴品。
XMLHttpRequest 用于在后臺(tái)與服務(wù)器交換數(shù)據(jù)。這意味著可以在不重新加載整個(gè)網(wǎng)頁的情況下简烘,對(duì)網(wǎng)頁的某部分進(jìn)行更新苔严。
創(chuàng)建 XMLHttpRequest 對(duì)象
所有現(xiàn)代瀏覽器(IE7+、Firefox孤澎、Chrome届氢、Safari 以及 Opera)均內(nèi)建 XMLHttpRequest 對(duì)象。
創(chuàng)建 XMLHttpRequest 對(duì)象的語法:
variable=new XMLHttpRequest();
老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 對(duì)象:
variable=new ActiveXObject("Microsoft.XMLHTTP");
為了應(yīng)對(duì)所有的現(xiàn)代瀏覽器覆旭,包括 IE5 和 IE6退子,請(qǐng)檢查瀏覽器是否支持 XMLHttpRequest 對(duì)象。如果支持型将,則創(chuàng)建 XMLHttpRequest 對(duì)象寂祥。如果不支持,則創(chuàng)建 ActiveXObject :
XMLHttpRequest 對(duì)象用于和服務(wù)器交換數(shù)據(jù)七兜。
向服務(wù)器發(fā)送請(qǐng)求
如需將請(qǐng)求發(fā)送到服務(wù)器丸凭,我們使用 XMLHttpRequest 對(duì)象的 open() 和 send() 方法:
xmlhttp.open("GET","test1.txt",true);
xmlhttp.send();
GET 還是 POST?
與 POST 相比腕铸,GET 更簡(jiǎn)單也更快惜犀,并且在大部分情況下都能用。
然而狠裹,在以下情況中虽界,請(qǐng)使用 POST 請(qǐng)求:
1.無法使用緩存文件(更新服務(wù)器上的文件或數(shù)據(jù)庫)
2.向服務(wù)器發(fā)送大量數(shù)據(jù)(POST 沒有數(shù)據(jù)量限制)
3.發(fā)送包含未知字符的用戶輸入時(shí),POST 比 GET 更穩(wěn)定也更可靠
GET 請(qǐng)求
一個(gè)簡(jiǎn)單的 GET 請(qǐng)求:
在上面的例子中涛菠,您可能得到的是緩存的結(jié)果浓恳。
為了避免這種情況,請(qǐng)向 URL 添加一個(gè)唯一的 ID:
如果您希望通過 GET 方法發(fā)送信息碗暗,請(qǐng)向 URL 添加信息:
xmlhttp.open("GET","demo_get2.asp?fname=Bill&lname=Gates",true);xmlhttp.send();
POST 請(qǐng)求
一個(gè)簡(jiǎn)單 POST 請(qǐng)求:
如果需要像 HTML 表單那樣 POST 數(shù)據(jù),請(qǐng)使用 setRequestHeader() 來添加 HTTP 頭梢夯。然后在 send() 方法中規(guī)定您希望發(fā)送的數(shù)據(jù):
url - 服務(wù)器上的文件
open() 方法的url參數(shù)是服務(wù)器上文件的地址:
xmlhttp.open("GET","ajax_test.asp",true);
該文件可以是任何類型的文件言疗,比如 .txt 和 .xml,或者服務(wù)器腳本文件颂砸,比如 .asp 和 .php (在傳回響應(yīng)之前噪奄,能夠在服務(wù)器上執(zhí)行任務(wù))死姚。
異步 - True 或 False?
AJAX 指的是異步 JavaScript 和 XML(Asynchronous JavaScript and XML)勤篮。
XMLHttpRequest 對(duì)象如果要用于 AJAX 的話都毒,其 open() 方法的 async 參數(shù)必須設(shè)置為 true:
xmlhttp.open("GET","ajax_test.asp",true);
對(duì)于 web 開發(fā)人員來說,發(fā)送異步請(qǐng)求是一個(gè)巨大的進(jìn)步碰缔。很多在服務(wù)器執(zhí)行的任務(wù)都相當(dāng)費(fèi)時(shí)账劲。AJAX 出現(xiàn)之前,這可能會(huì)引起應(yīng)用程序掛起或停止金抡。
通過 AJAX瀑焦,JavaScript 無需等待服務(wù)器的響應(yīng),而是:
1.在等待服務(wù)器響應(yīng)時(shí)執(zhí)行其他腳本
2.當(dāng)響應(yīng)就緒后對(duì)響應(yīng)進(jìn)行處理
Async = true
當(dāng)使用 async=true 時(shí)梗肝,請(qǐng)規(guī)定在響應(yīng)處于 onreadystatechange 事件中的就緒狀態(tài)時(shí)執(zhí)行的函數(shù):
Async = false
如需使用 async=false榛瓮,請(qǐng)將 open() 方法中的第三個(gè)參數(shù)改為 false:
xmlhttp.open("GET","test1.txt",false);
我們不推薦使用 async=false,但是對(duì)于一些小型的請(qǐng)求巫击,也是可以的禀晓。
請(qǐng)記住,JavaScript 會(huì)等到服務(wù)器響應(yīng)就緒才繼續(xù)執(zhí)行坝锰。如果服務(wù)器繁忙或緩慢粹懒,應(yīng)用程序會(huì)掛起或停止。
注釋:當(dāng)您使用 async=false 時(shí)什黑,請(qǐng)不要編寫 onreadystatechange 函數(shù) - 把代碼放到 send() 語句后面即可:
服務(wù)器響應(yīng)
如需獲得來自服務(wù)器的響應(yīng)崎淳,請(qǐng)使用 XMLHttpRequest 對(duì)象的 responseText 或 responseXML 屬性。
responseText 屬性
如果來自服務(wù)器的響應(yīng)并非 XML愕把,請(qǐng)使用 responseText 屬性拣凹。
responseText 屬性返回字符串形式的響應(yīng),因此您可以這樣使用:
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
responseXML 屬性
如果來自服務(wù)器的響應(yīng)是 XML恨豁,而且需要作為 XML 對(duì)象進(jìn)行解析嚣镜,請(qǐng)使用 responseXML 屬性:
請(qǐng)求books.xml文件,并解析響應(yīng):
onreadystatechange 事件
當(dāng)請(qǐng)求被發(fā)送到服務(wù)器時(shí)橘蜜,我們需要執(zhí)行一些基于響應(yīng)的任務(wù)菊匿。
每當(dāng) readyState 改變時(shí),就會(huì)觸發(fā) onreadystatechange 事件计福。
readyState 屬性存有 XMLHttpRequest 的狀態(tài)信息跌捆。
下面是 XMLHttpRequest 對(duì)象的三個(gè)重要的屬性:
在 onreadystatechange 事件中,我們規(guī)定當(dāng)服務(wù)器響應(yīng)已做好被處理的準(zhǔn)備時(shí)所執(zhí)行的任務(wù)象颖。
當(dāng) readyState 等于 4 且狀態(tài)為 200 時(shí)佩厚,表示響應(yīng)已就緒:
注釋:onreadystatechange 事件被觸發(fā) 5 次(0 - 4),對(duì)應(yīng)著 readyState 的每個(gè)變化说订。
使用 Callback 函數(shù)
callback 函數(shù)是一種以參數(shù)形式傳遞給另一個(gè)函數(shù)的函數(shù)抄瓦。
如果您的網(wǎng)站上存在多個(gè) AJAX 任務(wù)潮瓶,那么您應(yīng)該為創(chuàng)建 XMLHttpRequest 對(duì)象編寫一個(gè)標(biāo)準(zhǔn)的函數(shù),并為每個(gè) AJAX 任務(wù)調(diào)用該函數(shù)钙姊。
該函數(shù)調(diào)用應(yīng)該包含 URL 以及發(fā)生 onreadystatechange 事件時(shí)執(zhí)行的任務(wù)(每次調(diào)用可能不盡相同):
functionmyFunction(){loadXMLDoc("ajax_info.txt",function(){if(xmlhttp.readyState==4&& xmlhttp.status==200)? ? {document.getElementById("myDiv").innerHTML=xmlhttp.responseText;? ? }? });}
參考鏈接
https://segmentfault.com/a/1190000000351328
http://www.tuicool.com/articles/73maU3
http://www.cnblogs.com/mingmingruyuedlut/archive/2011/10/18/2216553.html