原生JS實現Ajax異步請求


原生JS實現Ajax請求

XMLHttpRequest對象

在IE7以下的瀏覽器,不支持原生XHR對象,需要使用MSXML庫中的XHR對象,有三種不同版本: MSXML2.XMLHttp、MSXML2.XMLHttp.3.0 和 MXSML2.XMLHttp.6.0。

如果要兼容這些瀏覽器,必須創建一個函數來處理兼容問題。

function createXHR(){
	if (typeof XMLHttpRequest != "undefined"){
		return new XMLHttpRequest();
	} else if (typeof ActiveXObject != "undefined"){
		if (typeof arguments.callee.activeXString != "string"){
			var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"], i, len;
			for (i=0,len=versions.length; i < len; i++){
				try {
					new ActiveXObject(versions[i]);
					arguments.callee.activeXString = versions[i];
					break;
				} catch (ex){
					//跳過
				}
			}
		}
		return new ActiveXObject(arguments.callee.activeXString);
	} else {
		throw new Error("No XHR object available.");
	}
} 

然后就可以使用var xhr = createXHR();來在所有瀏覽器中創建XHR對象了。

XHR的用法

get請求

使用XHR對象,要調用的第一個方法是open()方法,用來初始化請求,接受三個參數,分別是請求類型、請求URL、是否異步發送請求。
xhr.open("get", "demo.php", true);

要發送get請求,必須接着調用send()方法:xhr.send(null);

由於是異步請求,需要檢測一個狀態,等待數據接收完畢再處理請求。這個狀態通過readyState來表示。
readyState的值可以取0/1/2/3/4,分別代表未初始化、啟動、發送、接受、完成狀態。每次readyState改變都會觸發事件: readystatechange
注意,為了保證跨瀏覽器兼容性,需要在open方法之前指定 onreadystatechange 事件。

var xhr = createXHR();
xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
			alert(xhr.responseText);
		} else {
			alert("Request was unsuccessful: " + xhr.status);
		}
	}
};
xhr.open("get", 'demo.php', true);
xhr.send(null);

對於get請求URL的查詢字符串參數,可以使用encodeURIComponent來將參數轉化為合法的URL。

function addURLParam(url, name, value){
	url += (url.indexOf("?") == -1 ? "?" : "&");
	url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
	return url;
}

post請求

與get請求不同的是,post請求需要在send方法中,傳入數據參數。還需要設置http請求頭信息,將Content-Type設置為application/x-www-form-urlencoded

function submitData(id){
	var xhr = createXHR();
	xhr.onreadystatechange = function(){
		if (xhr.readyState == 4){
			if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
				alert(xhr.responseText);
			} else {
				alert("Request was unsuccessful: " + xhr.status);
			}
		}
	};
	xhr.open("post", "postexample.php", true);
	xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	var form = document.getElementById(id); // 將ID為id的表單中的數據序列化后發送給服務器
	xhr.send(serialize(form)); // 將表單數據序列化並發送
} 

serialize表單序列化函數:

function serialize(form){
	var parts = [],
	field = null,
	i,
	len,
	j,
	optLen,
	option,
	optValue;

	for (i=0, len=form.elements.length; i < len; i++){
		field = form.elements[i];

		switch(field.type){
			case "select-one":
			case "select-multiple":
			
			if (field.name.length){
				for (j=0, optLen = field.options.length; j < optLen; j++){ 
					option = field.options[j];
					if (option.selected){
						optValue = "";
						if (option.hasAttribute){
							optValue = (option.hasAttribute("value") ? option.value : option.text);
						} else {
							optValue = (option.attributes["value"].specified ? option.value : option.text);
						}
						parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue));
					}
				}
			}
			break;

			case undefined: //字段集
			case "file": //文件輸入
			case "submit": //提交按鈕
			case "reset": //重置按鈕
			case "button": //自定義按鈕
				break;

			case "radio": //單選按鈕
			case "checkbox": //復選框
				if (!field.checked){
					break;
				}
				/* 執行默認操作 */
			default:
				//不包含沒有名字的表單字段
				if (field.name.length){
					parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
				}
		}
	}
	return parts.join("&");
}

XMLHttpRequest進度事件

load: 在接收到完整的響應數據時觸發該事件。只支持IE8+以上的瀏覽器。

可以用來替代readystatechange事件,響應接收完畢就觸發load事件,因此沒有必要去檢查readyState屬性了。

var xhr = createXHR();
xhr.onload = function(){
	if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
		alert(xhr.responseText);
	} else {
		alert("Request was unsuccessful:" + xhr.status);
	}
};
xhr.open("get", "demo.php", true);
xhr.send(null);

詳情請見筆記: JavaScript高級程序設計: Ajax


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM