[TOC]
## 介紹
### xhr(即XMLHttpRequest)
> 是 `AJAX` 的基礎,用于在后臺與服務器交換數據
#### 1\. 優點:
* 在不重新加載頁面的情況下更新網頁
* 在頁面已加載后從服務器請求數據
* 在頁面已加載后從服務器接收數據
* 在后臺向服務器發送數據
#### 2\. 缺點:
* 書寫繁瑣,使用不方便
* 如果有多個請求,并且有依賴關系的話,容易形成回調地獄。
* 對于ie6、ie5需要寫兼容代碼
~~~
var xhr;
if (window.XMLHttpRequest) { // IE7+
?xhr = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE6、IE5
?xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.open('POST', url, true)
xhr.send(data)
xhr.onreadystatechange = function () {
?try {
? ?if (xhr.readyState === 4) {
? ? ?if (xhr.status === 200) {
? ? ? ?// successed
? ? ? ?callback(xhr.responseText);
? ? } else {
? ? ? ?// failed
? ? ? ?console.error("status error: ", xhr.status);
? ? }
? } else {
? ? ?// Not ready yet
? }
} catch (e) {
? ?alert('something wrong: ' + e);
}
}
~~~
#### 3\. 跨域支持度
不支持
### jQuery ajax
> 基于 `xhr` 的再封裝,可以簡單的使用 `$.get()` ,`$.post()` ,也可以完整書寫
~~~
$.ajax({
?type: 'POST',
?url: url,
?data: data,
?dataType: dataType,
?success: function () {},
?error: function () {}
})
~~~
#### 1\. 優點:
* 對 `xhr` 的封裝,做了兼容處理,簡化了使用。
* `dataType` 增加 `JSONP` 的支持,可處理部分跨域。
#### 2\. 缺點:
* 如果有多個請求,并且有依賴關系的話,容易形成回調地獄。
* 使用時需要引入 `jQuery` 。
#### 3\. 跨域支持度
支持 `JSONP` 跨域
> tips: `JSONP` 跨域僅支持 `get` 請求,且存在安全隱患。
### axios
是一個基于 `promise` 的 `HTTP` 庫,可用于瀏覽器與 `node.js` 中,本質還是對 `xhr` 的封裝,但是 `promise` 版
~~~
?
try {
?let res = await axios({
? ?method: "post",
? ?url: "xxx",
? ?data: data
});
?console.log("response", res);
} catch(error) {
?console.log("something error: ", error);
}
~~~
#### 1\. 優點:
* 支持 `Promise API`,解決了 “回調地獄” 問題。
* 提供了并發請求的接口(可同時發起多個請求)。
* 可攔截請求與響應。
* 自動轉換 `JSON` 數據。
* 客戶端支持防止 `CSRF`
> tips: 防止 `CSRF` , 就是讓你的每個請求都帶一個從 `cookie` 中拿到的 `key` , 后臺就可以據此輕松辨別出這個請求是否是用戶在假冒網站上的誤導輸入。
#### 2\. 缺點:
* 只支持現代瀏覽器
#### 3\. 跨域支持度
### fetch
使用原生 `js` 實現,不再使用 `xhr` 對象。
~~~
try {
?let response = await fetch(url);
?// successed
?let data = response.json();
} catch(error) {
?console.log("something error: ", error);
}
~~~
#### 1\. 優點:
* 支持 `Promise API` 。
* 脫離了 `xhr` ,是一種新的實現方式。
#### 2\. 缺點:
* `fetch` 只對網絡請求報錯,對于狀態碼為400、500都當做成功的請求,需要再次封裝
* `fetch` 默認不會帶 `cookie` ,需要添加配置項: `fetch(url, {credentials: "include"})` 。
* 不支持abort,不支持超時控制
* 無法監測請求的進度
#### 3\. 跨域支持度
在配置中,添加 `mode: "no-cors"` 就可以跨域了
~~~
fetch(url, {
? ?method: "post",
? ?mode: "no-cors",
? ?data: {}
}).then(() => { /* handle response */ });
~~~
## 區別
* `jQuery ajax` 與 `axios` :
* 相同點:
* 在 `xhr` 基礎上的改進版
* 簡化書寫方式
* 不同點:
* 前者依賴于 `jQuery` ,后者在 `xhr` 基礎上,結合使用 `Promise` 。
* 后者可攔截請求與響應,且解決了 “回調地獄” 問題。
* `xhr` 與 `fetch` 的:
* 相同點:
* 需要對狀態碼判斷處理,以確定請求響應狀態
* 不同點:
* 實現方式不同:前者基于 `ajax` ,后者由原生 `js` 實現。