自己封裝的XMLHttpRequest2 ajax

源碼:https://github.com/webery/ajax/tree/master

目前版本爲第一版,功能沒有完善,沒有經過嚴格測試,僅供學習參考.

測試代碼

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script type="text/javascript" src="/javascripts/ajax.js"></script>
	 <script type="text/javascript" src="/javascripts/jquery.js"></script>
	  <script type="text/javascript" src="/javascripts/ajaxAction.js"></script>
  </head>
  <body>
  <script type="text/javascript">//
    ajax({
	method:'GET',//
	responseType:'json',
    url:'http://localhost:3000/ajax',
    params: [{name:'yhj', age:{name:'yzh', age:'23'}},{name:'yhj', age:{name:'yzh', age:'23'}}],//[{name:'yhj', age:'22'},{name:'yzh', age:'23'}]
    }, {
    success:function(result) {
     alert(result)
     },
    }).send();
	
	/*
	ajaxAction({url:'http://localhost:3000/ajax', method:'POST'}, [{name:'yhj', age:{name:'yzh', age:'23'}},{name:'yhj', age:{name:'yzh', age:'23'}}], 
	{
	callbackHandler:function(result) {
	},
	});
  */
  </script>
  </body>
</html>

源代碼

/*
  ajax 封裝
  weber
  2015/7/5
  目前僅支持發送JSON數據,XML和html沒有處理
  Ajax的返回結果異常沒有處理提
*/

;(function(window, undefined) {

	function ajax(request, cbObject){
		 return new Ajax(request, cbObject);
	}
	//Ajax類定義
	/*request:
	   { method:請求的方法{GET,POST,PUT,DELETE},
	     requestType:發送信息至服務器時內容編碼類型,{默認值"application/x-www-form-urlencoded",'multipart/form-data', 'request payload'}
		 原生默認:Content-Type爲text/plain;charset=UTF-8,而請求表單參數在RequestPayload中
		 responseType:,{"" (空字符串),"arraybuffer","blob","document","json"(默認),"text"}
	     params:請求參數{DOMString:string(default)、Document:doc、FormData:formDate、Blob:blob、File:file、ArrayBuffer:buffer}
	   }
	*/
	//cbObject:回調對象{before(), success(result), after(), error(xhr, textStatus, error)}
	var RequestTypes = {
		default:'application/x-www-form-urlencoded;charset=utf-8;',
	};
	var Ajax = function(request, cbObject) {

		this.init(request, cbObject);
		return this;
	};

	//初始化參數
	Ajax.prototype.init = function(request, cbObject){

		var _req = request ? request : {};
		_req.method = _req.method ? _req.method : 'GET';
		_req.requestType = _req.requestType ? _req.requestType : 'application/x-www-form-urlencoded;charset=utf-8;';
		_req.responseType = _req.responseType ? _req.responseType : 'json';
		if(!(_req.params instanceof Document) && !(_req.params instanceof FormData)
			&& !(_req.params instanceof Blob) && !(_req.params instanceof ArrayBuffer)) {
			_req.params = _req.params ? MdataConvert(_req.params) : null;
			console.log(_req.params);
		}
		this.request = _req;
		this.headers = {};//暫時存儲set的Header,等到要發送請求的時候寫入xhr
		this.cbObject = cbObject;//回調對象
		this.xhr = getXhr();//初始化xhr
		this.xhr.responseType = _req.responseType;
	};
	/**
	send({DOMString、Document、FormData、Blob、File、ArrayBuffer})
	**/
	Ajax.prototype.send = function(callback){

		var cbObject = this.cbObject;
		if(cbObject.before) {
			if(!cbObject.before()) {
				return false;
			}
		}

		var xhr = this.xhr;
		var request = this.request;
		if(request.method.toUpperCase() == 'GET') {
			request.url = request.url + '?' + toQueryString(request.params);
			request.params = null;
		}
		else if(request.method.toUpperCase() == 'POST' && !request.params instanceof Blob) {
			request.params = toQueryString(request.params);
		}
		xhr.open(request.method, request.url);
		//判斷請求數據類型
		this.setHeader('Content-type', request.requestType);
		
		this.writeHeader();//把請求太寫入xhr
		console.log(request.params.get('radio'))
		xhr.send(request.params);
		
		var responseType = request.responseType;
		xhr.onreadystatechange = function() {
			if(xhr.readyState == 4) {
				if(xhr.status == 200 || xhr.status == 304) {
					var result = xhr.response;//設置xhr的responseType屬性後就從這裏取返回值
					//var result = xhr.responseText || xhr.responseXML || xhr.response;
					cbObject.success(result);
				}
				else {
					if(cbObject.error) {
						cbObject.error(xhr, xhr.textStatus, error);
					}
				}
			}
		};

		if(cbObject.after) {
			cbObject.after();
		}
	};
	//{"" (空字符串),"arraybuffer","blob","document","json","text"}
	Ajax.prototype.setResponseType = function(type){
		this.xhr.responseType = type;
	};
	//設置單個請求頭,重複會覆蓋
	Ajax.prototype.setHeader = function(key, value){
		this.headers[key] = value;
	};
	//獲取單個請求頭,不存在返回undefined
	Ajax.prototype.getHeader = function(key){
		return this.headers[key];
	};
	//設置單個請求頭,{}的形式
	Ajax.prototype.setHeaders = function(hObj){
		for(var key in hObj) {
			this.headers[key] = hObj[key];
		}
	};
	//獲取所有的請求頭
	Ajax.prototype.getHeaders = function(){
		return this.headers;
	};
	//把緩存的請求頭寫入xhr
	Ajax.prototype.writeHeader = function(){
		var headers = this.headers;
		var xhr = this.xhr;
		for(var key in headers) {
			this.xhr.setRequestHeader(key, headers[key]);
		}
	};
	Ajax.prototype.overrideMimeType = function(mimetype){
		this.xhr.overrideMimeType(mimetype);
	};
	
	Ajax.prototype.setTimeout = function(time){
		this.xhr.timeout = time;
	};
	
	Ajax.prototype.onTimeout = function(fn){
		this.xhr.ontimeout = fn;
	};
	//下載,event.total是需要傳輸的總字節,event.loaded是已經傳輸的字節。如果event.lengthComputable不爲真,則event.total等於0。
	Ajax.prototype.onDownProgress = function(fn){
		this.xhr.onprogress = fn;
	};
	//上傳
	Ajax.prototype.onUploadProgress = function(fn){
		this.xhr.upload.onprogress = fn;
	};
	//傳輸成功完成
	Ajax.prototype.onLoad = function(fn){
		this.xhr.load = fn;
	};
	//傳輸被用戶取消
	Ajax.prototype.onAbort = function(fn){
		this.xhr.abort = fn;
	};
	Ajax.prototype.abort = function(fn){
		this.xhr.abort.apply(this.xhr);
	};
	//傳輸中出現錯誤
	Ajax.prototype.onError = function(fn){
		this.xhr.error = fn;
	};
	//傳輸開始
	Ajax.prototype.onLoadstart = function(fn){
		this.xhr.loadstart = fn;
	};
	//傳輸結束,但是不知道成功還是失敗
	Ajax.prototype.onLoadEnd = function(fn){
		this.xhr.loadEnd = fn;
	};
	
	//跨瀏覽器獲取xhr,不支持Ajax返回null
	function getXhr() {
		var xhr = null;
		if(window.XMLHttpRequest){
			xhr = new XMLHttpRequest();
		}
		else if(window.ActiveXObject){
			xhr = new ActiveXObject('Microsoft.XMLHTTP');
		}

		return xhr;
	}
	//數據類型獲取
	var Mtypeof = function(source){
		var typeofString = Object.prototype.toString.call(source);
		return typeofString.substring(typeofString.lastIndexOf("\ ") + 1, typeofString.lastIndexOf("\]"));
	}
	//數據類型轉換
	var MdataConvert = function(objData, objName){
		var data = arguments[0] ? objData : {};
		var prefix = arguments[1] ? objName : '';
		var output = {};
		switch (Mtypeof(data)) {
			case 'Object':
				prefix = prefix.length>0 ? (prefix + '.') : '';
			for(var key in data){
				if(Mtypeof(data[key]) == 'String') {
					output[prefix + key] = data[key];
				}
				else {
					merge(output, MdataConvert(data[key], prefix + key));
				}
			}
			break;
			case "Array":
			for(var i=0; i<data.length; i++){
				if(Mtypeof(data[i]) == 'String') {
					output[prefix + '[' + i + ']'] = data[i];
				}
				else {
					merge(output, MdataConvert(data[i], prefix + '[' + i + ']'));
				}
			}
			break;
			default:
			output[prefix] = data.toString();
			break;
		}
		return output;
	}
	//和nodejs的merge一樣,把source的屬性拷貝給target,會發生覆蓋
	function merge(target, source) {
		if (target && source) {
			for (var key in source) {
				target[key] = source[key];
			}
		}
		return target;
	}
	
	//把對象的數據轉換成&形式的string
	function toQueryString(data) {
		var query = '', i,
			push = function (key, value) {
			query += encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
			}, key, value;
			
			for (key in data) {
				if (!Object.hasOwnProperty.call(data, key)) {
					continue;
			}
			
			value = data[key];
			if ((typeof (data) === 'object') && (data instanceof Array)) {
				for (i = 0; i < value.length; i++) {
					push(key, value[i]);
				}
			} else {
				push(key, data[key]);
			}
		}
		return query.replace(/&$/, '').replace(/%20/g, '+');
	}

	window.ajax = ajax;
})(window);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章