AJAX大总结
1、AJAX概述
1.1 什么是AJAX
AJAX(Asynchronous Javascript And XML)翻譯成中文就是“異步Javascript和XML”。即使用Javascript語言與服務(wù)器進(jìn)行異步交互,傳輸?shù)臄?shù)據(jù)為XML(當(dāng)然,傳輸?shù)臄?shù)據(jù)不只是XML)。
AJAX還有一個(gè)最大的特點(diǎn)就是,當(dāng)服務(wù)器響應(yīng)時(shí),不用刷新整個(gè)瀏覽器頁面,而是可以局部刷新。這一特點(diǎn)給用戶的感受是在不知不覺中完成請(qǐng)求和響應(yīng)過程。
1.2. 同步交互與異步交互
1.3. AJAX常見應(yīng)用情景
當(dāng)我們?cè)诎俣戎休斎胍粋€(gè)“傳”字后,會(huì)馬上出現(xiàn)一個(gè)下拉列表!列表中顯示的是包含“傳”字的10個(gè)關(guān)鍵字。
其實(shí)這里就使用了AJAX技術(shù)!當(dāng)文件框發(fā)生了輸入變化時(shí),瀏覽器會(huì)使用AJAX技術(shù)向服務(wù)器發(fā)送一個(gè)請(qǐng)求,查詢包含“傳”字的前10個(gè)關(guān)鍵字,然后服務(wù)器會(huì)把查詢到的結(jié)果響應(yīng)給瀏覽器,最后瀏覽器把這10個(gè)關(guān)鍵字顯示在下拉列表中。
當(dāng)輸入用戶名后,把光標(biāo)移動(dòng)到其他表單項(xiàng)上時(shí),瀏覽器會(huì)使用AJAX技術(shù)向服務(wù)器發(fā)出請(qǐng)求,服務(wù)器會(huì)查詢名為zhangSan的用戶是否存在,最終服務(wù)器返回true表示名為zhangSan的用戶已經(jīng)存在了,瀏覽器在得到結(jié)果后顯示“用戶名已被注冊(cè)!”。
1.4 AJAX的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
缺點(diǎn):
?
2、AJAX技術(shù)
2.1 AJAX第一例(發(fā)送GET請(qǐng)求)
2.1.1 準(zhǔn)備工作
因?yàn)锳JAX也需要請(qǐng)求服務(wù)器,異步請(qǐng)求也是請(qǐng)求服務(wù)器,所以我們需要先寫好服務(wù)器端代碼,即編寫一個(gè)Servlet!
這里,Servlet很簡單,只需要輸出“Hello AJAX!”。
| public class AServlet extends HttpServlet { ??? public void doGet(HttpServletRequest request, HttpServletResponse response) ?????????? throws ServletException, IOException { ?????? System.out.println("Hello AJAX!"); ?????? response.getWriter().print("Hello AJAX!"); ??? } } |
2.1.2 AJAX核心(XMLHttpRequest)
其實(shí)AJAX就是在Javascript中多添加了一個(gè)對(duì)象:XMLHttpRequest對(duì)象。所有的異步交互都是使用XMLHttpRequest對(duì)象完成的。也就是說,我們只需要學(xué)習(xí)一個(gè)Javascript的新對(duì)象即可。
注意,各個(gè)瀏覽器對(duì)XMLHttpRequest的支持也是不同的!大多數(shù)瀏覽器都支持DOM2規(guī)范,都可以使用:var xmlHttp = new XMLHttpRequest()來創(chuàng)建對(duì)象
為了處理瀏覽器兼容問題,給出下面方法來創(chuàng)建XMLHttpRequest對(duì)象:
| ??? function createXMLHttpRequest() { ?????? var xmlHttp; ?????? // 適用于大多數(shù)瀏覽器,以及IE7和IE更高版本 ?????? try{ ?????????? xmlHttp = new XMLHttpRequest(); ?????? } catch (e) { ?????????? // 適用于IE6 ?????????? try { ????????????? xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); ?????????? } catch (e) { ????????????? // 適用于IE5.5,以及IE更早版本 ????????????? try{ ????????????????? xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); ????????????? } catch (e){} ?????????? } ?????? }????????? ?????? return xmlHttp; ??? } |
2.1.3 打開與服務(wù)器的連接(open方法)
當(dāng)?shù)玫?/span>XMLHttpRequest對(duì)象后,就可以調(diào)用該對(duì)象的open()方法打開與服務(wù)器的連接了。open()方法的參數(shù)如下:
open(method, url, async):
| ?????? var xmlHttp = createXMLHttpRequest(); ?????? xmlHttp.open("GET", "/ajaxdemo1/AServlet", true); |
2.1.4 發(fā)送請(qǐng)求
當(dāng)使用open打開連接后,就可以調(diào)用XMLHttpRequest對(duì)象的send()方法發(fā)送請(qǐng)求了。send()方法的參數(shù)為POST請(qǐng)求參數(shù),即對(duì)應(yīng)HTTP協(xié)議的請(qǐng)求體內(nèi)容,若是GET請(qǐng)求,需要在URL后連接參數(shù)。
注意:若沒有參數(shù),需要給出null為參數(shù)!若不給出null為參數(shù),可能會(huì)導(dǎo)致FireFox瀏覽器不能正常發(fā)送請(qǐng)求!
| ?????? xmlHttp.send(null); |
2.1.5 接收服務(wù)器響應(yīng)
當(dāng)請(qǐng)求發(fā)送出去后,服務(wù)器端Servlet就開始執(zhí)行了,但服務(wù)器端的響應(yīng)還沒有接收到。接下來我們來接收服務(wù)器的響應(yīng)。
XMLHttpRequest對(duì)象有一個(gè)onreadystatechange事件,它會(huì)在XMLHttpRequest對(duì)象的狀態(tài)發(fā)生變化時(shí)被調(diào)用。下面介紹一下XMLHttpRequest對(duì)象的5種狀態(tài):
onreadystatechange事件會(huì)在狀態(tài)為1、2、3、4時(shí)引發(fā)。
下面代碼會(huì)被執(zhí)行四次!對(duì)應(yīng)XMLHttpRequest的四種狀態(tài)!
| ?????? xmlHttp.onreadystatechange = function() { ?????????? alert('hello'); ?????? }; |
但通常我們只關(guān)心最后一種狀態(tài),即讀取服務(wù)器響應(yīng)結(jié)束時(shí),客戶端才會(huì)做出改變。我們可以通過XMLHttpRequest對(duì)象的readyState屬性來得到XMLHttpRequest對(duì)象的狀態(tài)。
| ?????? xmlHttp.onreadystatechange = function() { ?????????? if(xmlHttp.readyState == 4) { ????????????? alert('hello');?? ?????????? } ?????? }; |
其實(shí)我們還要關(guān)心服務(wù)器響應(yīng)的狀態(tài)碼是否為200,其服務(wù)器響應(yīng)為404,或500,那么就表示請(qǐng)求失敗了。我們可以通過XMLHttpRequest對(duì)象的status屬性得到服務(wù)器的狀態(tài)碼。
最后,我們還需要獲取到服務(wù)器響應(yīng)的內(nèi)容,可以通過XMLHttpRequest對(duì)象的responseText得到服務(wù)器響應(yīng)內(nèi)容。
responsXML是xml格式的文本,是document對(duì)象
| ?????? xmlHttp.onreadystatechange = function() { ?????????? if(xmlHttp.readyState == 4 && xmlHttp.status == 200) { ????????????? alert(xmlHttp.responseText);??? ?????????? } ?????? }; |
2.1.6 AJAX第一例小結(jié)
XMLHttpRequest對(duì)象的5種狀態(tài):
通常我們只關(guān)心4狀態(tài)。
XMLHttpRequest對(duì)象的status屬性表示服務(wù)器狀態(tài)碼,它只有在readyState為4時(shí)才能獲取到。
XMLHttpRequest對(duì)象的responseText屬性表示服務(wù)器響應(yīng)內(nèi)容,它只有在readyState為4時(shí)才能獲取到!
? <script type="text/javascript">var xmlHttp = new XMLHttpRequest();xmlHttp.open("GET", "/AJAX/AServlet");xmlHttp.send(null);xmlHttp.onreadystatechange = function(){if(xmlHttp.readyState == 4 && xmlHttp.status == 200){var h1 = document.getElementById("h1");h1.innerHTML = xmlHttp.responseText;}}</script><body><h1 id="h1"></h1></body> public class AServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.getWriter().print("hehe");}}?
2.2 AJAX第二例(發(fā)送POST請(qǐng)求)
2.2.1 發(fā)送POST請(qǐng)求注意事項(xiàng)
POST請(qǐng)求必須設(shè)置ContentType請(qǐng)求頭的值為application/x-www.form-encoded。表單的enctype默認(rèn)值就是為application/x-www.form-encoded!因?yàn)槟J(rèn)值就是這個(gè),所以大家可能會(huì)忽略這個(gè)值!當(dāng)設(shè)置了<form>的enctype=” application/x-www.form-encoded”時(shí),等同與設(shè)置了Cotnent-Type請(qǐng)求頭。
但在使用AJAX發(fā)送請(qǐng)求時(shí),就沒有默認(rèn)值了,這需要我們自己來設(shè)置請(qǐng)求頭:
| xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); |
?
當(dāng)沒有設(shè)置Content-Type請(qǐng)求頭為application/x-www-form-urlencoded時(shí),Web容器會(huì)忽略請(qǐng)求體的內(nèi)容。所以,在使用AJAX發(fā)送POST請(qǐng)求時(shí),需要設(shè)置這一請(qǐng)求頭,然后使用send()方法來設(shè)置請(qǐng)求體內(nèi)容。
| xmlHttp.send("b=B"); |
?
這時(shí)Servlet就可以獲取到這個(gè)參數(shù)!!!
?
AServlet
| ??? public void doPost(HttpServletRequest request, HttpServletResponse response) ?????????? throws ServletException, IOException { ?????? System.out.println(request.getParameter("b")); ?????? System.out.println("Hello AJAX!"); ?????? response.getWriter().print("Hello AJAX!"); ??? } |
ajax2.jsp
| <script type="text/javascript"> function createXMLHttpRequest() { ??? try { ?????? return new XMLHttpRequest();//大多數(shù)瀏覽器 ??? } catch (e) { ?????? try { ?????????? return new ActiveXObject("Msxml2.XMLHTTP"); ?????? } catch (e) { ?????????? return new ActiveXObject("Microsoft.XMLHTTP"); ?????? } ??? } } ? function send() { ??? var xmlHttp = createXMLHttpRequest(); ??? xmlHttp.onreadystatechange = function() { ?????? if(xmlHttp.readyState == 4 && xmlHttp.status == 200) { ?????????? var div = document.getElementById("div1"); ?????????? div.innerHTML = xmlHttp.responseText; ?????? } ??? }; ??? xmlHttp.open("POST", "/ajaxdemo1/AServlet?", true); ??? xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); ??? xmlHttp.send("b=B"); } </script> |
| <h1>AJAX2</h1> <button onclick="send()">測試</button> <div id="div1"></div> |
?
2.3 AJAX第三例(用戶名是否已被注冊(cè))
2.3.1 功能介紹
在注冊(cè)表單中,當(dāng)用戶填寫了用戶名后,把光標(biāo)移開后,會(huì)自動(dòng)向服務(wù)器發(fā)送異步請(qǐng)求。服務(wù)器返回true或false,返回true表示這個(gè)用戶名已經(jīng)被注冊(cè)過,返回false表示沒有注冊(cè)過。
客戶端得到服務(wù)器返回的結(jié)果后,確定是否在用戶名文本框后顯示“用戶名已被注冊(cè)”的錯(cuò)誤信息!
2.3.2 案例分析
2.3.3 代碼
regist.jsp
| ??? <script type="text/javascript"> ??????? function ajax(){ ??????????? var userText = document.getElementById("username"); ??????????? var username = userText.value; ??????????? var xmlHttp = new XMLHttpRequest(); ??????????? xmlHttp.open("GET", "<c:url value="/ValidateUserNameServlet"/>?username="+username ); ??????????? xmlHttp.send(null); ??????????? xmlHttp.onreadystatechange = function(){ ??????????????? if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ ?????????????????? var span = document.getElementById("span1"); ?????????????????? if(xmlHttp.responseText == "true"){ ?????????????????????? span.innerHTML = "用戶名可用"; ?????????????????? }else{ ?????????????????????? span.innerHTML = "用戶名已被注冊(cè)"; ?????????????????? } ??????????????? } ??????????? } ??????? } ??? </script>? |
| ? <form action="" method="post"> ? ? 用戶名:<input type="text"id = "username" name="username" onblur="ajax()"><span id="span1"></span><br> ? ? <input type="submit" > ? </form> |
RegistServlet.java
| ??? public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ??????? String username = request.getParameter("username"); ??????? System.out.println(username); ??????? if(username.equals("admin")){ ??????????? response.getWriter().print(false); ??????? }else{ ??????????? response.getWriter().print(true); ??????? } ??? } |
?
總結(jié)
- 上一篇: leetcode259. 较小的三数之和
- 下一篇: Date类的构造方法以及成员方法220