什麼是 AJAX?

日誌 > 技術交流
設置置頂 | 編輯 | 刪除

什麼是 AJAX?

發表於:2008年3月6日 21時47分10秒閱讀(2)評論(0)本文鏈接:http://user.qzone.qq.com/592433424/blog/1204811230
AJAX (異步 JavaScript 和 XML) 是個新產生的術語,專爲描述JavaScript的兩項強大性能.這兩項性能在多年來一直被網絡開發者所忽略,直到最近Gmail, Google suggest和google Maps的橫空出世才使人們開始意識到其重要性.

  這兩項被忽視的性能是:

     * 無需重新裝載整個頁面便能向服務器發送請求.
     * 對XML文檔的解析和處理.

  步驟 1 – "請!" --- 如何發送一個HTTP請求

  爲了用JavaScript向服務器發送一個HTTP請求, 需要一個具備這種功能的類實例.

這樣的類首先由Internet Explorer以ActiveX對象引入, 被稱爲XMLHTTP. 後來Mozilla, Safari 和其他

瀏覽器紛紛仿效, 提供了XMLHttpRequest類,它支持微軟的ActiveX對象所提供的方法和屬性.

  因此, 爲了創建一個跨瀏覽器的這樣的類實例(對象), 可以應用如下代碼:

if (window.XMLHttpRequest) { // Mozilla, Safari, ...
    http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
    http_request = new ActiveXObject("Microsoft.XMLHTTP");
}

  (上例對代碼做了一定簡化,這是爲了解釋如何創建XMLHTTP類實例.

實際的代碼實例可參閱本篇步驟3.)

  如果服務器的響應沒有XML mime-type header,某些Mozilla瀏覽器可能無法正常工作. 爲了解決這個

問題, 如果服務器響應的header不是text/xml,可以調用其它方法修改該header.

http_request = new XMLHttpRequest();
http_request.overrideMimeType('text/xml');

  接下來要決定當收到服務器的響應後,需要做什麼.這需要告訴HTTP請求對象用哪一個JavaScript函數

處理這個響應.可以將對象的onreadystatechange屬性設置爲要使用的JavaScript的函數名,如下所示:

http_request.onreadystatechange = nameOfTheFunction;

  注意:在函數名後沒有括號,也無需傳遞參數.另外還有一種方法,可以在扉頁(fly)中定義函數及其對

響應要採取的行爲,如下所示:

http_request.onreadystatechange = function(){
    // do the thing
};

  在定義瞭如何處理響應後,就要發送請求了.可以調用HTTP請求類的open()和send()方法, 如下所示:

http_request.open('GET', 'http://www.example.org/some.file', true);
http_request.send(null);

     * open()的第一個參數是HTTP請求方式 – GET, POST, HEAD 或任何服務器所支持的您想調用的方式

. 按照HTTP規範,該參數要大寫;否則,某些瀏覽器(如Firefox)可能無法處理請求.有關HTTP請求方法的詳

細信息可參考http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html W3C specs
     * 第二個參數是請求頁面的URL.由於自身安全特性的限制,該頁面不能爲第三方域名的頁面.同時一定

要保證在所有的頁面中都使用準確的域名,否則調用open()會得到"permission denied"的錯誤提示.一個

常見的錯誤是訪問站點時使用domain.tld,而當請求頁面時,卻使用www.domain.tld.
     * 第三個參數設置請求是否爲異步模式.如果是TRUE, JavaScript函數將繼續執行,而不等待服務器響

應.這就是"AJAX"中的"A".

  如果第一個參數是"POST",send()方法的參數可以是任何想送給服務器的數據. 這時數據要以字符串

的形式送給服務器,如下所示:

name=value&anothername=othervalue&so=on

  步驟 2 – "收到!" --- 處理服務器的響應

  當發送請求時,要提供指定處理響應的JavaScript函數名.

http_request.onreadystatechange = nameOfTheFunction;

  我們來看看這個函數的功能是什麼.首先函數會檢查請求的狀態.如果狀態值是4,就意味着一個完整的

服務器響應已經收到了,您將可以處理該響應.

if (http_request.readyState == 4) {
    // everything is good, the response is received
} else {
    // still not ready
}

  readyState的取值如下:

    * 0 (未初始化)
    * 1 (正在裝載)
    * 2 (裝載完畢)
    * 3 (交互中)
    * 4 (完成)

(Source)

  接着,函數會檢查HTTP服務器響應的狀態值. 完整的狀態取值可參見 W3C site. 我們着重看值爲200

OK的響應.

if (http_request.status == 200) {
    // perfect!
} else {
    // there was a problem with the request,
    // for example the response may be a 404 (Not Found)
    // or 500 (Internal Server Error) response codes
}

  在檢查完請求的狀態值和響應的HTTP狀態值後, 您就可以處理從服務器得到的數據了.有兩種方式可

以得到這些數據:

    * http_request.responseText – 以文本字符串的方式返回服務器的響應
    * http_request.responseXML –

以XMLDocument對象方式返回響應.處理XMLDocument對象可以用JavaScript DOM函數

  步驟 3 – "萬事俱備!" - 簡單實例

  我們現在將整個過程完整地做一次,發送一個簡單的HTTP請求. 我們用JavaScript請求一個HTML文件,

test.html, 文件的文本內容爲"I'm a test.".然後我們"alert()"test.html文件的內容.



    var http_request = false;

    function makeRequest(url) {

        http_request = false;

        if (window.XMLHttpRequest) { // Mozilla, Safari,...
            http_request = new XMLHttpRequest();
            if (http_request.overrideMimeType) {
                http_request.overrideMimeType('text/xml');
            }
        } else if (window.ActiveXObject) { // IE
            try {
                http_request = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    http_request = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {}
            }
        }

        if (!http_request) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
            return false;
        }
        http_request.onreadystatechange = alertContents;
        http_request.open('GET', url, true);
        http_request.send(null);

    }

    function alertContents() {

        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                alert(http_request.responseText);
            } else {
                alert('There was a problem with the request.');
            }
        }

    }



  本例中:

    * 用戶點擊瀏覽器上的"請求"鏈接;
    * 接着函數makeRequest()將被調用.其參數 – HTML文件test.html在同一目錄下;
    * 這樣就發起了一個請求.onreadystatechange的執行結果會被傳送給alertContents();
    * alertContents()將檢查服務器的響應是否成功地收到,如果是,就會"alert()"test.html文件的內

容.

  步驟 4 – "X-文檔" --- 處理XML響應

  在前面的例子中,當服務器對HTTP請求的響應被收到後,我們會調用請求對象的reponseText屬性.該屬

性包含了test.html文件的內容.現在我們來試試responseXML屬性.

  首先,我們新建一個有效的XML文件,後面我們將使用這個文件.該文件(test.xml)源代碼如下所示:



    I'm a test.


  在該腳本中,我們只需修改請求部分:

...
οnclick="makeRequest('test.xml')">
...

  接着,在alertContents()中,我們將alert()的代碼alert(http_request.responseText);換成:

var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);

  這裏,我們使用了responseXML提供的XMLDocument對象並用DOM方法獲取存於XML文件中的內容.

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=599314
 
評論列表
請選擇道具
<textarea class="content" id="commentEditor" style="BORDER-RIGHT: #ccc 1px solid; BORDER-TOP: #ccc 1px solid; BORDER-LEFT: #ccc 1px solid; COLOR: gray! important; BORDER-BOTTOM: #ccc 1px solid" οnfοcus="getUBBeditor(this)" rows="13" cols="50" name="content">點擊這裏發表評論</textarea>
溫馨提示:點擊驗證碼輸入框,以獲取驗證碼
請輸入驗證碼:
     
<script type="text/javascript"> // function jumpToTop() { if(isSmall) { document.body.scrollTop = 0; } else parent.$('mbody').scrollTop = 0; } function _quote(s){ s=s.replace(//[quote/=引自:(.+?)(?:/x20|&nbsp;){1,2}於/x20(.+?)/x20發表的評論/]/g,"/x03引自:<cite>$1</cite>&nbsp;&nbsp;於 <ins>$2</ins> 發表的評論<br />/x02").replace(//[//quote/]/g,"/x01"); for(var i=0;i<2;i++) s=s.replace(//x03([^/x03/x01/x02]*?)/x02([^/x03/x01/x02]*?)/x01/g, function(a,b,c){ return '<blockquote style="width:400px;border:dashed 1px gray;margin:10px;padding:10px">'+b+'引用內容:<br /><br /><q>'+c+'</q></blockquote>'; }); return s.replace(/[/x03/x02/x01]/g,""); } var bLoaded = false; function checkMsgReply(obj) { if(!bLoaded) top.includeJS('/qzone/blog/script/common.js', function(){bLoaded=true;checkMsgReply(obj)}, document); else checkReply(obj); if(obj.checked){ MAX_COMMENT_LEN = 500; } else { MAX_COMMENT_LEN = 4500; } _fontCount = MAX_COMMENT_LEN; //字數限制 if(!window.sendCommentEditor) return; if(sendCommentEditor.editorArea.editMode == 1) toCountFont(sendCommentEditor.id, "html"); else toCountFont(sendCommentEditor.id, "text"); } function showMsgLeftCnt() { if(!bLoaded) top.includeJS('/qzone/blog/script/common.js', function(){bLoaded=true;showMsgLeftCnt();}, document); else showLeftSMS(); } function selectBlogPaper() { if(checkLogin() <= 10000) { top.showLoginBox("mall"); return; } if(!!top.g_JData["blogContent"]) { if(parent.g_iLoginUin == parent.g_iUin) { location.href="/qzone/newblog/blogeditor.html?paperid=" + parent.g_JData["blogContent"].data.lp_id + "&paperstyle=" + parent.g_JData["blogContent"].data.lp_style + "&paperdialog=1"; } else { parent.location.href="http://user.qzone.qq.com/" + parent.g_iLoginUin + "/addNewBlog?paperid=" + parent.g_JData["blogContent"].data.lp_id + "&paperstyle=" + parent.g_JData["blogContent"].data.lp_style; } } else { top.showMsgBox("抱歉,暫時無法獲取該信紙信息!", 1, 2000); } } /** * 批量刪除中選擇全選 */ function selectAllComments(bChecked) { var oList = document.getElementsByName("commentCheckBox"); if(oList.length==0) return; for(var i=0; i<oList.length; ++i){ oList[i].checked = !!bChecked; } } function showCommentCheckBoxs(bShow, bCheck){ var oList = document.getElementsByName("commentCheckBox"); if(oList.length==0) return; for(var i=0; i<oList.length; ++i){ oList[i].style.display = ((!!bShow) ? "" : "none"); if(!!bCheck) oList[i].checked = true; else oList[i].checked = false; } if(!!bCheck) $("batchSelAllInput").checked = true; else $("batchSelAllInput").checked = false; $("leftDeleteComParag").style.display = ((!!bShow) ? "" : "none"); $("batchDelComHref").style.display = ((!!bShow) ? "none" : ""); $("noBatchDelComHref").style.display = ((!!bShow) ? "" : "none"); } /** * 名博批量刪除評論 */ function deleteBatchComments() { if(!contentProperty) return; var oList = document.getElementsByName("commentCheckBox"); if(oList.length==0) { return; } var tmp; var strCommentList = ''; var strArchList = ''; var nDeleteCnt = 0; for(var i=0; i<oList.length; ++i){ if(oList[i].checked) { tmp = oList[i].value.split('_') strCommentList += ('-' + tmp[0]); strArchList += ('-' + tmp[1]); ++nDeleteCnt; } } strCommentList = strCommentList.substr(1); strArchList = strArchList.substr(1); if(nDeleteCnt == 0) { parent.showMsgbox("請選擇要刪除的評論", 0, 2000); return; } if(!!contentProperty && contentProperty.totalCommentNumber < nDeleteCnt) return; if(!confirm("您是否要刪除選中的用戶評論?")) return; parent.loadXMLAsyncNoCache("delBatchReply", "http://"+BLOG_DOMAIN+CGI_PATH+"blog_batch_del_comment", function(){ if(parent.g_XDoc["delBatchReply"].selectNodes("error").length > 0){ dalert(null, parent.g_XDoc["delBatchReply"].xml, 2000); delete parent.g_XDoc["delBatchReply"]; return; } dalert(null, parent.g_XDoc["delBatchReply"].xml, 2000, 2); contentProperty.totalCommentNumber -= nDeleteCnt; //清理cache with(contentProperty){ delete parent.g_XDoc["blogRoot"].contentHSList[currentBlogid]; pageList = {}; pageIndexMap = []; currentCommentPage = lastCommentPage = (!contentProperty.nowaPage)?0:nowaPage[3]; parent.g_XDoc["blogRoot"].replyNumUpdateHSmap[currentBlogid] = totalCommentNumber; parent.isRefreshTop = true; if(currentCommentPage == 0) { setTimeout(contentInit, 1000); } else{ var tp = Math.ceil(totalCommentNumber/PAGE_COMMENT_NUM); var num = totalCommentNumber%PAGE_COMMENT_NUM; if(num==0 || currentCommentPage<tp-1) num = PAGE_COMMENT_NUM; getOnePageComment(num, nowaPage[0], nowaPage[1], nowaPage[2], blogCommentListCallback, 1); $("commentCount3").innerHTML = totalCommentNumber; } } delete top.g_XDoc["delBatchReply"]; showCommentCheckBoxs(false, false); }, function(){ dalert(null, BUSY_MSG, 2000); delete parent.g_XDoc["delBatchReply"]; }, "uin="+parent.g_iLoginUin+"&blogid="+contentProperty.currentBlogid+"&archlist="+strArchList.URLencode()+"&replyidlist="+strCommentList.URLencode() ); } /** * 有評論或沒有時顯示/隱藏相關element */ function showElementsAnyReply(bShow) { var strCss = !!bShow ? "" : "none"; if(isStar && parent.g_iUin == parent.g_iLoginUin) { $("starDeleteComDiv").style.display = strCss; } if(parent.g_bBlogShowCheatHint == true) $("commentHintDiv").style.display = strCss; } /** * 關閉提防上當提示信息 */ function closeCheatHint() { parent.g_bBlogShowCheatHint = false; $('commentHintDiv').style.display = 'none'; } setLoginStatus(); var frmComment=document.getElementById("commendForm"); if(!isSmall) document.body.οnkeydοwn=scrollBlog; if((isStar || isBiz) && (top.g_iLoginUin!=top.g_iUin)){ frmComment.hassign.checked=false; $("startToolSelect").style.display="none"; } if(top.g_iLoginUin>10000 && top.g_iLoginUin!=top.g_iUin) { $("msgboardSelfReply").style.display = ""; $("blogSelPaper").title = "我也要使用此信紙寫日誌"; } setTimeout(contentInit,50); // </script>  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章