js——XHR知識歸納


XHLHttpRequest對象

ajax技術能夠向服務器請求額外的數據而無需卸載頁面。其核心技術是XMLHttpRequest對象(XHR)。
IE7之前的舊版本通過MSXML庫中的ActiveX對象實現。而IE7及之后的瀏覽器支持XMLHttpRequest構造函數
可以做兼容性的createXHR();

function createXHR(){
		//檢查是否支持XMLHttpRequest
		if(typeof XMLHttpRequest!="undefined")
		{
			//支持,返回XMLHttpRequest對象
			return new XMLHttpRequest();
		}
		//如果不支持XMLHttpRequest,就檢查是否支持ActiveXObject
		else if(typeof ActiveXObject !="undefined")
		{
			//檢查activeXString
			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){
						//跳過
					}
				}
			}
			//返回ActiveXObject
			return new ActiveXObject(arguments.callee.activeXString);
		}
		else
		{
			//都不行
			throw new Error("NO XHR object availablle");
		}
	}

這個例子先檢查XHR對象是否存在,存在就返回XHR對象,不存在就檢查ActiveX對象是否存在,存在就返回,如果兩個對象都不存在,就返回錯誤。

XHR的使用

XHR有一個方法叫open(),接收三個參數,請求方式(get,post),請求的url,表示是否異步請求的布爾值(true為異步)

let xhr=createXHR();
xhr=open('get','https://www.baidu.com',flase);

open()方法不會直接發送請求,而是啟用一個請求以備發送

XHR還有一個方法叫send(),接收一個參數,即作為請求主體要發送的數據。
send()和open()配合使用就可以發送特定的請求

xhr=open('get','https://www.baidu.com',flase);
xhr.send(null);

上面代碼是同步執行的,所以要等服務器響應請求后js代碼才會繼續執行。服務器響應后會自動為XHR對象填充以下信息:

屬性 描述
responseText 作為響應主題被返回的文本
responseXML 如果響應的內容是"text/xml"或"application/xml",這個屬性將保存響應數據的XML DOM文檔 ,如果不是xml文件,這個值為空
status HTTP的響應狀態
statusText HTTP響應狀態說明

狀態判斷

盡量不要用statusText去判斷,statusText在跨域時不太可靠。

if((xhr.status>=200&&xhr.status<=300)||xhr.status===304)
	{
		//success
		console.log("status success");
	}
	else
	{
		console.log("status fail");
	}

注意:瀏覽器有時候會錯誤的報告204狀態,IE的XHR的ActiveX會將201設置為1223,IE中原生的XHR會將204規范為200,而opera或將status設置為0。

請求/響應的活動階段

可以檢測XHR對象的readyState屬性來求得請求/響應的當前階段

  • 0:未開始,還沒有調用open()方法。
  • 1:啟用,調用open()方法
  • 2:發送,調用send()方法
  • 3:接收,服務器接收到部分請求
  • 4:完成,服務器接收到所有請求,而且客戶端可以使用了。

這些階段的改變會觸發readystatechange事件,可以根據該事件來檢測readyState

	//onreadystatechange事件要在open之前指定,保證跨域瀏覽器的兼容性
	xhr.onreadystatechange=function(){
		if(xhr.readyState===4)
		{
			if((xhr.status>=200&&xhr.status<=300)||xhr.status===304)
			{
				//success
				console.log("status success");
			}
			else
			{
				console.log("status fail");
			}
		}
	}


	xhr.open("get","https://www.baidu.com",true);
	xhr.send(null);

可以用xhr.abort()在響應前取消異步請求,
這個方法會使XHR停止觸發時間,再也不允許訪問與響應有關的對象屬性,這個方法在請求終止后還會對XHR解引,不建議XHR重用,會影響內存。

請求頭

  • 不同瀏覽器發送的信息可能有所不同
  • 設置:setRequestHeader()方法可以自定義頭部信息,接收兩個參數頭部字段的名稱和頭部字段的值,但是必須在open()與send()之間調用
xhr.open("get","www.baidu.com",true);
// 不要使用瀏覽器正常字段,會影響瀏覽器響應
xhr.setRequestHeader("MyHeader","MyValue");
xhr.send(null);

響應頭

  • 獲取:getResponseHeader(),傳入頭部字段的名稱,獲得相應的響應頭信息
  • 獲取全部:getAllResponseHeaders(),取得一個包含所有頭部信息的長字符串
var MyHeader=xhr.getResponseHeader('Content-Type');
var allHeader=xhr.getAllResponseHeader();

Get請求

get請求常用於向服務器查詢某些信息。

//這里的查詢字符串需要正確的編碼
xhr.open("get","example.php?name=name1&age=age1",true);

GET請求經常發生的錯誤是查詢字符串的格式問題,查詢字符串中的每個參數名和值都需要encodeURIComponent()來先進行編碼。

/**
	 * [對查詢字符串進行編碼]
	 * @param {[type]} url   [要添加的參數的url]
	 * @param {[type]} name  [參數名]
	 * @param {[type]} value [參數值]
	 */
	function addURLParam(url,name,value)
	{
		url+=(url.indexOf("?")===-1?"?":"&");
		url+=encodeURIComponent(name)+"="+encodeURIComponent(value);
		return url;
	}

使用這個函數可以保證查詢字符串的格式良好,能可靠的用於XHR對象

POST請求

post請求用於向服務器發送應該被保存的數據,把數據作為請求主體提交。
post請求可以提交XML文檔

xhr.open("post","example.php",true)
xhr.send(data);

默認情況下,服務器對post請求和Web表單提交不會一視同仁。如果需要提交表單,可以使用如下代碼

/**
	 * post提交表單
	 * @return {[type]} [description]
	 */
	function submitData(){
		var xhr=createXHR();
		xhr.onreadystatechange=function(){
		if(xhr.readyState===4)
		{
			if((xhr.status>=200&&xhr.status<=300)||xhr.status===304)
			{
				//success
				console.log("status success");
			}
			else
			{
				console.log("status fail");
			}
		}
		}

		xhr.open("post","example.php",true);
		//設置頭部信息為表單提交時的內容
		xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		var form=document.getElementById("user-info");
		//將表單數據序列化
		xhr.send(serialize(form));
	}


免責聲明!

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



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