詳解ajax、fetch、axios的區(qū)別
眾所周知它們都用來發(fā)送請求,其實它們區(qū)別還蠻大的。這也是面試中的高頻題,本文將詳細進行講解。
1. ajax
英譯過來是Aysnchronous JavaScript And XML,直譯是異步JS和XML(XML類似HTML,但是設計宗旨就為了傳輸數據,現已被JSON代替),解釋一下就是說以XML作為數據傳輸格式發(fā)送JS異步請求。但實際上ajax是一個一類技術的統(tǒng)稱的術語,包括XMLHttpRequest、JS、CSS、DOM等,它主要實現網頁拿到請求數據后不用刷新整個頁面也能呈現最新的數據。
下面我們簡單封裝一個ajax請求【面試高頻題】:
const ajaxGet = function (url) {
const xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status < 400) {
console.log(xhr.response); // 響應結果
}
}
}
xhr.onerror = (error) => {
console.log(error, xhr.status)
}
xhr.send()
}
2. fetch
它其實就是一個JS自帶的發(fā)送請求的一個api,拿來跟ajax對比是完全不合理的,它們完全不是一個概念的東西,適合拿來和fetch對比的其實是xhr,也就是上面封裝ajax請求的代碼里的XMLHttpRequest,這兩都是JS自帶的發(fā)請求的方法,而fetch是ES6出現的,自然功能比xhr更強,主要原因就是它是基于Promise的,它返回一個Promise,因此可以使用.then(res => )的方式鏈式處理請求結果,這不僅提高了代碼的可讀性,還避免了回調地獄(xhr通過xhr.onreadystatechange= () => {}這樣回調的方式監(jiān)控請求狀態(tài),要是想在請求后再發(fā)送請求就要在回調函數內再發(fā)送請求,這樣容易出現回調地獄)的問題。而且JS自帶,語法也非常簡潔,幾行代碼就能發(fā)起一個請求,用起來很方便,據說大佬都愛用。
它的特點是:
- 使用 promise,不使用回調函數。
- 采用模塊化設計,比如 rep、res 等對象分散開來,比較友好。
- 通過數據流對象處理數據,可以提高網站性能。
下面我們簡單寫個fetch請求的示例:
// get請求
fetch('http://127.0.0.1:8000/get')
.then(res => {
if (!res.ok) {
throw new Error('請求錯誤!狀態(tài)碼為:', res.status)
}
return res.text()
}).then(data => {
console.log(data);
})
// post請求
fetch('http://127.0.0.1:8000/post', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
mode: 'no-cors', // 設置cors表示只能發(fā)送跨域的請求,no-cors表示跨不跨域都能發(fā)
body: JSON.stringify({
name: 'zhangsan',
age: 18
})
}).then(res => {
return res.json()
}).then(data => {
console.log(data);
})
3. axios
axios是用于網絡請求的第三方庫,它是一個庫。axios利用xhr進行了二次封裝的請求庫,xhr只是axios中的其中一個請求適配器,axios在nodejs端還有個http的請求適配器;axios = xhr + http;它返回一個Promise。【項目中經常需要封裝的axios】
它的特點:
- 在瀏覽器環(huán)境中創(chuàng)建 XMLHttpRequests;在node.js環(huán)境創(chuàng)建 http 請求
- 返回Promise
- 攔截請求和響應
- 自動轉換 JSON 數據
- 轉換請求數據和響應數據
- 取消請求
它的基礎語法是:
// 發(fā)送 Get 請求
axios({
method: 'get',
url: '',
params: {} // 查詢query使用params
})
// 發(fā)送 Post 請求
axios({
method: 'post',
url: '',
data: {} // 請求體body用data
})
下面我們在vue項目中封裝一個使用axios實現的請求。
libs/config.js:配置文件
const serverConfig = {
baseUrl: "http://127.0.0.1:8000", // 請求基礎地址,可根據環(huán)境自定義
useTokenAuthentication: false, // 是否開啟token認證
};
export default serverConfig;
libs/request.js:封裝請求
import axios from "axios"; // 第三方庫 需要安裝
import serverConfig from "./config";
// 創(chuàng)建axios實例
const apiClient = axios.create({
baseURL: serverConfig.baseUrl, // 基礎請求地址
withCredentials: false, // 跨域請求是否需要攜帶cookie
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
timeout: 10000, // 請求超時時間
});
// 請求攔截
apiClient.interceptors.request.use(
(config) => {
// 請求發(fā)送前的處理邏輯 比如token認證,設置各種請求頭啥的
// 如果開啟token認證
if (serverConfig.useTokenAuthentication) {
// 請求頭攜帶token
config.headers.Authorization = localStorage.getItem("token");
}
return config;
},
(error) => {
// 請求發(fā)送失敗的處理邏輯
return Promise.reject(error);
}
);
// 響應攔截
apiClient.interceptors.response.use(
(response) => {
// 響應數據處理邏輯,比如判斷token是否過期等等
// 代碼塊
return response;
},
(error) => {
// 響應數據失敗的處理邏輯
let message = "";
if (error && error.response) {
switch (error.response.status) {
case 302:
message = "接口重定向了!";
break;
case 400:
message = "參數不正確!";
break;
case 401:
message = "您未登錄,或者登錄已經超時,請先登錄!";
break;
case 403:
message = "您沒有權限操作!";
break;
case 404:
message = `請求地址出錯: ${error.response.config.url}`;
break;
case 408:
message = "請求超時!";
break;
case 409:
message = "系統(tǒng)已存在相同數據!";
break;
case 500:
message = "服務器內部錯誤!";
break;
case 501:
message = "服務未實現!";
break;
case 502:
message = "網關錯誤!";
break;
case 503:
message = "服務不可用!";
break;
case 504:
message = "服務暫時無法訪問,請稍后再試!";
break;
case 505:
message = "HTTP 版本不受支持!";
break;
default:
message = "異常問題,請聯系管理員!";
break;
}
}
return Promise.reject(message);
}
);
export default apiClient;
/api/index.js:配置請求接口,這里一個get一個post
import apiClient from "@/libs/request";
let getInfo = (params) => {
return apiClient({
url: "/get",
method: "get",
params, // axios的get請求query用params
});
};
let postInfo = (params) => {
return apiClient({
url: "/post",
method: "post",
data: params, // axios的post請求body用data
});
};
export default {
getInfo,
postInfo,
};
App.vue:用于測試請求結果
<script>
import api from './api/index.js'
export default {
data() {
return {
isH5: true
}
},
created() {
this.init()
},
methods: {
init() {
api.getInfo().then(res => {
console.log(res.data);
})
api.postInfo({
name: 'zhangsan',
age: '18'
}).then(res => {
console.log(res.data);
})
}
},
}
</script>
結果如下:


4. 總結
總結一部分區(qū)別如下:【這三個東西差別真的很大】
| Ajax | fetch | axios | |
|---|---|---|---|
| 類型 | 術語,技術的統(tǒng)稱 | js內置的api | 第三方庫 |
| 是否使用xhr二次封裝 | 是 | 否 | 是 |
| 是否返回Promise | 否 | 是 | 是 |
到此這篇關于詳解ajax、fetch、axios的區(qū)別的文章就介紹到這了,更多相關ajax fetch axios內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
僅Firefox中鏈接A無法實現模擬點擊以觸發(fā)其默認行為
偶然發(fā)現之前寫的事件模塊在Firefox5中無法觸發(fā)A的默認行為了。IE/Opera/Firefox5中A具有click方法,因此模擬點擊直接調用click方法即可。2011-07-07

