天天看點

實用js/jq的ajax詳解

Ajax:Asynchronous JavaScript and XML(異步JavaScript和XML)。

是指一種建立互動式、快速動态網頁應用的網頁開發技術,無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。

功能:節省使用者操作時間,提高使用者體驗,局部重新整理減少資料請求;

我們要知道,其實Ajax就是去請求背景接口拿資料的,前端拿到背景的資料後就用這些資料進行dom操作以相應的樣式輸出到頁面中。(最難的地方就是對擷取到的資料進行分析和處理并渲染到頁面上)

一、我們首先來看一個get請求的ajax流程(js代碼):

//建立一個ajax對象(類似于打開浏覽器)
var xhr = XMLHttpRequest
    ? new XMLHttpRequest()
    : new ActiveXObject('Microsoft.XMLHTTP'); //new ActiveXObject('Microsoft.XMLHTTP') 這個我們是對低版本IE浏覽器進行相容性處理

//使用ajax對象下面的open方法告知浏覽器請求的方式(相當于在位址欄輸入位址)
xhr.open('get','1.txt',true);

//送出(相當于按Enter鍵)
xhr.send();    //在這一步才會發送網絡請求(上面是準備工作)

//等待伺服器傳回内容
xhr.onreadystatechange = function() {    // 監測readyState狀态值變化
    if ( xhr.readyState == 4 ) { // readyState狀态值為4表示響應内容解析完成,可以在用戶端調用了
        if ( xhr.status == 200) {  //200表示http請求正确
            alert( xhr.responseText ); // responseText 為背景傳回的資料 
        } else {
            alert('出錯了,Err:' + xhr.status);   //傳回錯誤響應的http狀态碼
        }
    }
    
}
           

二、接下來我們詳細分析一下請求ajax的流程:

1、建立一個ajax對象

(建立了ajax對象之後才能使用ajax對象下面的方法和屬性)

2、使用ajax對象下面的open()方法
open('get','url',true)方法
接收三個參數:
	1.請求方式(get、post 或者其他)
	2.位址(請求的背景接口位址)
	3.是否異步(true為異步;false為同步)
           

異步:非阻塞 ajax請求的代碼不會影響後面代碼的執行(ajax請求的代碼就算沒執行完也能執行後面的代碼)

同步:阻塞 ajax請求的代碼會影響後面代碼的執行(ajax請求的關聯的代碼一定要執行完才能繼續執行後面的代碼)

(1)、get請求方式

get請求方式是通過

url?

後面的參數值傳送的(根據後端提供的接口請求參數來傳入傳輸的,多個參數之間用&連接配接)(格式要正确填寫)

(ajax參數的格式都是

參數名1=參數值1&參數名2=參數值2....

注意:get請求存在如下兩個問題

1.會緩存(其實我們背景資料已經變了,我們希望在重新整理位址欄的時候,頁面資料會變動。但是因為get請求方式位址不改變,内容就不會變。) 這時我們需要在url?後面連接配接一個随機數,時間戳

new Date().getTime()

(這樣就每一次通路的都是不一樣的位址)

2.中文會出現亂碼 用編碼

encodeURI()

解決

如:

(2)、post請求方式

請求資料的參數是在請求頭中(那麼資料就不能直接在url後面傳入參數了)。

xhr.open('post','post.php',true);
//一定要申明發送的資料類型(ajax沒有預設的編碼方式,表單送出有)
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
//post請求方式,資料放在send()裡面作為參數傳遞
xhr.send('username=劉偉&age=30');
           

注意:post沒有緩存問題(無需設定時間戳),也不會有出現中文亂碼問題(無需編碼)

3、使用ajax對象下面的send()方法

向伺服器發送請求。

(1)、get方式,無需傳入參數

xhr.send()

(2)、post方式,需要傳入背景需要的參數

xhr.send(‘多個參數使用&分隔’)

4、等待伺服器響應并傳回資料

下面介紹ajax對象下面的屬性,當有它們的值有相關變化時,說明伺服器有相關的響應了。

readyState : ajax工作狀态(有五個值)

0 (初始化)還沒有調用open()方法

1 (載入)已調用send()方法,正在發送請求

2 (載入完成)send()方法完成,已收到全部響應内容

3 (解析)正在解析響應内容

4 (完成)響應内容解析完成,可以在用戶端調用了

onreadystatechange : 當readyState改變的時候觸發(可能會觸發很多次)

responseText : ajax請求傳回的資料内容就被存放到這個屬性下面(通過調用這個屬性就能擷取到傳回的内容,均為字元串格式)

status : 伺服器狀态,http狀态碼(容錯處理)

http狀态碼:
1xx:訓示資訊——表示請求已接收,繼續處理
2xx:成功——表示請求已經被成功接收
3xx:重定向——要完成的請求必須進行進一步操作
4xx:用戶端錯誤——請求有文法錯誤或者請求無法實作
5xx:伺服器錯誤——伺服器未能實作合法的請求
           

三、jq和 js的完整請求方式(隻介紹常用的文法)

我們都知道在jquery中使用ajax很友善,因為已經幫我們封裝好了。

1、jquery使用ajax:
$.ajax({
	url : '請求的接口位址url',
	data : '需要傳給背景的參數',
	type : 'post',   //預設是get
	dataType:"json",  // 預期伺服器傳回的資料類型,預設為json
	success : function(data){   //成功擷取資料後的回調函數
		// data為背景傳回的資料,通過處理data資料來渲染頁面
	},
	error : function(err){        //擷取資料失敗後的回調函數
		// err 為背景請求錯誤後傳回的錯誤資訊
		console.log(err)
	}
});
           
2、javascript封裝ajax(隻封裝了get和post請求方式),使得像jquery的使用方式
//封裝實參覆寫形參的函數
function extend(obj1, obj2) {
    for (var attr in obj2) {
        obj1[attr] = obj2[attr];
    }
}
// 将data中傳入的json對象轉為name=winne&age=18&like={"jk":2}&arr=[1,2]這種格式
function paramData (json) {
	let str = ''
	for (let key in json) {
		if (typeof json[key] === 'object') {
			str += `${key}=${JSON.stringify(json[key])}&`
		}else{
			str += `${key}=${json[key]}&`
		}
		
	}
	return str.substring(0, str.length - 1)
	
	// 上面的代碼可以用下面的代碼代替
	// let resultStr = Object.keys(json).map( (key) => {
    //	let value = json[key]
   	//	if (typeof value === 'object') {
    // 		value = JSON.stringify(value)
    //	}
    //	return `${key}=${value}`
   // }).join('&')
   // return resultStr
}
function ajax(opt) {
    defaultOpt = {  //預設函數參數
    "method":'get', //預設為get傳輸
    "data":'',  //預設沒有參數
    "url":'',
    "dataType":"json", //預設傳回json類型的資料
    "success": function(data){} //預設擷取到資料後什麼都不做
    },
    "error":function(err){}
   extend(defaultOpt, opt);  //配置參數指派給預設參數
   // 建立一個支援ajax的對象
    var xhr = XMLHttpRequest
            ? new XMLHttpRequest()
            : new ActiveXObject('Microsoft.XMLHTTP'); 
    if (defaultOpt.method == 'get' && defaultOpt.data) {  //調用預設參數
        defaultOpt.url += '?' + paramData(defaultOpt.data); //get請求的完整url拼接
    }
    xhr.open(defaultOpt.method:toLowerCase() , defaultOpt.url, true);
    if (defaultOpt.method:toLowerCase()  == 'get') {
        xhr.send();
    } else if(defaultOpt.method:toLowerCase()  == 'post'){
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
        xhr.send(paramData(defaultOpt.data));
    }
    //等待伺服器響應并傳回資料
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {                
                defaultOpt.success && defaultOpt.success(xhr.responseText);  //可變的地方用參數傳入,代碼塊就用函數傳入

            } else {
				defaultOpt.error&& defaultOpt.error(xhr);
               // console.log('出錯了' + xhr);
            }
        }
    }
}


// 調用js封裝好後的ajax
ajax({
	url : '請求的接口位址url',
	data : { // 傳給背景的參數
		name: 'winne',
		age: 18,
		like: {jk: 2},
		arr: [1, 2]
	},
	type : 'post',   //預設是get
	success : function(data){   //成功擷取資料後的回調函數
		// data為背景傳回的資料,通過處理data資料來渲染頁面
		// 我們最常用的是JSON.parse(data)來把字元串json轉化為真正的json來進行資料處理;
		// 使用 JSON.stringfy(json)來把json資料轉化為json字元串
	},
	error : function(err){        //擷取資料失敗後的回調函數
		// err 為背景請求錯誤後傳回的錯誤資訊
		console.log(err)
	}
})

           

繼續閱讀