標籤:des style blog http io ar os 使用 java
今天決定學習一下Ajax非同步XMLHttpRequest對象,平時一直使用jQuery.ajax()就萬事大吉,
當自己要實現一套時才發現當中的細節事情!jQuery源碼真的博大精深優美得很;
先從w3cschool看一下基本的使用方式,參考的jQ版本是v1.11.1
http://www.w3school.com.cn/xml/xml_http.asp
基本流程是先做簡單XMLHttpRequest相容處理,提交請求,最後是回調處理結果;
setup1 配置
開始時候在想怎樣才能寫出優美的參數傳值,看jQ源碼發現是使用jQuery.extend,而且這函數在很多地方都在應用,看來分量很重噢;
手冊介紹是用一個或多個其他對象來擴充一個對象,返回被擴充的對象;如果不指定target,則給jQuery命名空間本身進行擴充。
jQ是先定義了基本參數對象ajaxSettings#8830行開始;然後調用ajaxSetup方法,其實這貨還是調用了jQuery.extend去合并對象;只是判斷是否是擴充設定物件;
自己太賴了只做最簡參數單合并和擷取回調方法事情;
function ajaxSetup(opations) {if (typeof opations == ‘object‘) {for (key in opations) { //Code....}}return ajaxSetting;}
setup2
執行個體化XMLHttpRequest就交由兩個方法isWindowXHR和isIEXHR,然後由JS自行判斷使用哪一個;
這裡基本沒什麼特別!jQuery基本也是這麼乾的!只是它還做了很多IE6~9的瀏覽器安全色代碼(難關jQ2就放棄治療它們)
// Create the request object // (This is still attached to ajaxSettings for backward compatibility) jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?// Support: IE6+function() {// XHR cannot access local files, always use ActiveX for that casereturn !this.isLocal &&// Support: IE7-8// oldIE XHR does not support non-RFC2616 methods (#13240)// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9// Although this check for six methods instead of eight// since IE also does not support "trace" and "connect"/^(get|post|head|put|delete|options)$/i.test( this.type ) &&createStandardXHR() || createActiveXHR();} :// For all other browsers, use the standard XMLHttpRequest objectcreateStandardXHR;
我萬惡地幾行沒養分的代碼就好了!
var xmlHttp = isWindowXHR() || isIEXHR(); function isWindowXHR() {//Code....}function isIEXHR() {//Code....}
setup3 傳值請求伺服器和處理回調
這裡jQ做了很多參數值的過濾、是否是跨域請求、head部分組裝,是否跨域分開了好像是兩部分處理(不知道有沒有看錯!代碼太長了)
搜源碼jQuery.ajaxTransport可以找到;
然後也是跟XMLHttpRequest流程定義調用send處理onreadystatechange在不同狀態觸發事件;
//TODO:增加其他狀態處理function stateChange() {if (xmlHttp.readyState == 4) {//Code....}}return {‘ajax‘ : function(opations) {var settings = ajaxSetup(opations);if (xmlHttp !== null && settings) {xmlHttp.onreadystatechange = stateChange;switch(settings[‘type‘].toUpperCase()){case ‘POST‘://Code....break;case ‘GET‘://Code....break;}} else {alert("Your browser does not support XMLHTTP.");}}};
在這次學習中發現一個很好的網站
whatwg.org
後來發現這傢伙跟W3C是很有冤緣;
詳細看這裡《哪個HTML5?WHATWG與W3C或分道揚鑣》
http://www.cnblogs.com/xesam/archive/2012/07/23/2604254.html
完整代碼:
index.html
<DOCTYPE html><html><head><meta charset="utf-8"><title></title><script type="text/javascript" src="xhr.js"></script></head><body><input type="button" id="gTime" value="擷取伺服器時間" /><div id="serTime">00:00:00</div></body></html><script type="text/javascript">gTime.addEventListener("click", function(){$.ajax({type: "POST",url: "xmlHttpRequestAction.php",dataType : ‘json‘,async : true,data: "name=John&location=Boston",success : function(msg) {var obj = eval(‘(‘ + msg + ‘)‘);serTime.childNodes[0].nodeValue = obj.date;console.log(obj);}});}, false);</script>
xhr.js
var $ = (function(Global){var xmlHttp = isWindowXHR() || isIEXHR();var callback = {};var ajaxSetting = {//TODO:過濾地址符號,例如結尾的"/"‘url‘ : location.href,‘type‘ : ‘GET‘,//TODO:增加類型轉換判斷‘dataType‘ : ‘text‘,‘async‘ : true,//TODO:增加支援物件類型‘data‘ : null};function isWindowXHR() {try {if (window.XMLHttpRequest) {return new XMLHttpRequest();}} catch (e) {}}function isIEXHR() {try {if (window.ActiveXObject) {return new ActiveXObject("Microsoft.XMLHTTP");}} catch (e) {}}function ajaxSetup(opations) {if (typeof opations == ‘object‘) {for (key in opations) {if (typeof ajaxSetting[key] !== ‘undefined‘) {ajaxSetting[key] = opations[key];} else {switch(typeof opations[key]){case ‘function‘:callback[key] = opations[key];break;}}}}return ajaxSetting;}//TODO:增加其他狀態處理function stateChange() {if (xmlHttp.readyState == 4) {if (xmlHttp.status == 200) {if (callback.success) {//Successreturn callback.success(xmlHttp.responseText);} else {return xmlHttp.response;}} else {alert("Problem retrieving XML data");}}}/* https://xhr.spec.whatwg.org/ */return {‘ajax‘ : function(opations) {var settings = ajaxSetup(opations);if (xmlHttp !== null && settings) {xmlHttp.onreadystatechange = stateChange;switch(settings[‘type‘].toUpperCase()){case ‘POST‘:xmlHttp.open(‘POST‘, settings[‘url‘], settings[‘async‘]);xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");xmlHttp.send(ajaxSetting[‘data‘]);break;case ‘GET‘:settings[‘url‘] += (‘?‘ + ajaxSetting[‘data‘]);xmlHttp.open(‘GET‘, settings[‘url‘], settings[‘async‘]);xmlHttp.send(null);break;}} else {alert("Your browser does not support XMLHTTP.");}}};})(window);
xmlHttpRequestAction.php
<?phpdate_default_timezone_set("PRC");echo json_encode(array(‘date‘=>date(‘Y-m-d h:i:s‘),‘POST‘=>$_POST,‘GET‘=>$_GET, ‘content‘=>‘中文‘));?>
原生XMLHttpRequest學習日誌