1. 原生AJAX
所謂的Ajax就是異步的javascript和xml.所謂異步就是在不影響用戶的操作下發送請求過程,xml是一個數據格式,不過現在在ajax交互中,大家使用更爲簡單的json。
我們都知道,ajax只是瀏覽器與服務器進行數據交互的方式之一,遵循HTTP協議,請求方式爲Get請求和POST提交,如果爲POST提交方式的時候,瀏覽器中的數據將會被封裝到請求報文中,此時問題出來了。如何格式化請求的數據???幾個意思呢?是這樣,舉個例子,如果此時瀏覽器想給服務器發送一組數據 {id:1001,name:'terry'}
,學過JS的同學都知道,這是JS中的一個對象,但是在HTTP協議中,是不允許傳遞對象的,因爲在文本中無法表示一個對象,這裏就有了對象序列化的概念,就是將對象轉換爲一種文本描述,比如xml,再比如json,再比如查詢字符串。到底將數據轉換爲哪種格式呢?這時候要前後臺協商一下,因爲不同的序列化(編碼)方式會影響後臺開發者接受參數。所謂協議就是這樣的一種東西,你可以在協議中聲明你發送的數據各位爲xml/json/querystring中的一種,然後你一定要記住,要把參數按照這個數據格式進行編碼,否則你就違背了協議!
如下,是我使用原生的XMLHttpRequest封裝的一個post方法
let post = ({url,data,successHandler,errorHandler})=>{
//1. 實例化XMLHttpRequest對象
let xhr = new XMLHttpRequest();
//2. 打開請求
xhr.open('post',url);
//3. 設定返回值類型爲json
xhr.responseType = "json";
//4. 設置頭部信息
xhr.setRequestHeader('Accept','application/json');
//* 當前數據編碼爲表單編碼
//xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
//* 當前數據編碼爲json
xhr.setRequestHeader('Content-Type','application/json')
xhr.onreadystatechange = function(){
//console.log(this.readystate);
if(this.readyState == 4){
if(this.status == 200){
// success
successHandler(this.response);
} else {
//
errorHandler(this.response);
}
}
};
//5. 直接請求
//將數據轉換爲查詢字符串
xhr.send(data);
//xhr.send(urlEncoded(data));
//將數據轉換爲json
xhr.send(JSON.stringify(data));
}
在上述代碼中,我通過 xhr.setRequestHeader('Content-Type','application/json')
這段代碼來聲明標準,也就是說:看好嘍,我給你發的數據格式爲application/json
也就是所謂的json。然後在發送數據的時候我一定要 xhr.send(JSON.stringify(data));
,這個代碼的意思發送數據的時候我將數據序列化爲JSON字符串。
好了,如果我想要發送給後臺查詢字符串的話該怎麼辦?還是要兩步,第一步:設置請求頭信息,告知後臺我的數據格式xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
。第二步進行數據編碼xhr.send(qs.stringify(data));
。注意這裏的qs爲一個查詢字符串轉化的庫,參照https://www.npmjs.com/package/qs
2. jQuery中的ajax
明白了原生ajax的交互方式,那麼第三方框架的交互方式就好理解了。我們先看一下jquery中的$.ajax方法。語法是這樣的
$.ajax({
url:'',
method:'',
dataType:''
contentType:'application/x-www-form-urlencoded; charset=UTF-8',
data:{},
headers:{},
processData:true
...
})
以上ajax中的參數是在數據交互中比較關鍵的幾個屬性,url,method,contentType比較簡單,分別代表請求地址,請求方式,期待服務器返回數據類型,dataType 的值不固定,而是Intelligent Guessersh,根據返回值的內容來決定是xml, json, script, or html。
- data ,發送給服務端的數據,如果是一個對象,默認會將該對象轉換爲查詢字符串,如果是get請求,那麼這個查詢字符串會拼接到請求地址後。好了,這裏提到了默認轉換爲查詢字符串,我們在上面說過,一定要分兩步,第一請求頭部聲明,第二數據格式轉換。這裏既然做了轉換,肯定會有請求頭部聲明,那就是contentType參數,該參數的默認值爲
application/x-www-form-urlencoded; charset=UTF-8
. - processData ,默認爲true,也就是默認會讓jquery將data中的對象轉換爲查詢字符串。
好了,如果這時後臺需要我們發送json數據化該怎麼辦?
$.ajax({
processData:false,
contentType:'application/json',
data:JSON.stringify({
})
})
在上述代碼中,processData:false
表示禁用jquery的默認編碼功能,contentType:'application/json'
設置請求頭部信息,聲明當前請求數據格式爲json。最後再給data傳值的時候,需要先對數據進行序列化,將對象序列化爲JSON字符串。這樣就可以發送一個JSON格式的數據了。
3. axios
axios又是另外一套Ajax框架,基於Promise的,更加純粹的AJAX框架,在vue開發中使用axios會更爲方便的。
axios({
url:'',
method:'',
baseURL:'',
responseType:'json',
headers:{
},
params:{
},
paramsSerializer:{}
data:{
},
transformRequest:[],
transformResponse:[],
})
以上,url與method與jquery中類似,表示請求地址和請求方式。baseURL是比jquery強大的地方,可以爲所有請求設置基路徑,也就是說真正的請求地址應該是 baseURL+url。
- responseType ,與jQuery中的dataType類似,表示期待服務端返回的數據類型,默認爲JSON。
- headers , 可以設定請求頭信息
- params , 請求參數,一般是在請求地址上攜帶的,注意與data的區別
- paramsSerializer ,序列化params
- data , 在請求體中的數據,發送到服務器。 僅僅在請求方式爲'PUT', 'POST','PATCH' 的情況下才能使用,另外,如果transformRequest設定爲空,data必須爲string, ArrayBuffer, hash, Stream
- transformRequest ,在數據發送的服務端之前,修改data數據
- transformResponse ,在響應數據發送到then catch之前處理響應數據
好了,明確了這些參數後,我們考慮,如何發送json數據
axios.post('',{id:1001,name:'terry})
由於默認headers中爲'Content-Type':'application/json'
,同時發送post請求的時候axios會將data中的數據轉換爲json.所以我們無需複雜處理即可發送json格式的數據。
那麼,如果發送查詢字符串嗎?還是之前的兩步操作,第一設置請求頭信息,第二在請求前修改數據編碼。
axios.defaults.headers.post['Content-type']='application/x-www-form-urlencoded';
axios.defaults.transformRequest=[function(data){ qs.stringify(data);}]
axios.post('',{id:1001,name:'terry})