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


4. 總結(jié)
總結(jié)一部分區(qū)別如下:【這三個(gè)東西差別真的很大】
| Ajax | fetch | axios | |
|---|---|---|---|
| 類(lèi)型 | 術(shù)語(yǔ),技術(shù)的統(tǒng)稱(chēng) | js內(nèi)置的api | 第三方庫(kù) |
| 是否使用xhr二次封裝 | 是 | 否 | 是 |
| 是否返回Promise | 否 | 是 | 是 |
到此這篇關(guān)于詳解ajax、fetch、axios的區(qū)別的文章就介紹到這了,更多相關(guān)ajax fetch axios內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript制作網(wǎng)頁(yè)圖片上實(shí)現(xiàn)下雨效果
這里給大家分享的是一則使用javascript實(shí)現(xiàn)在網(wǎng)頁(yè)圖片上下雨的特效,效果非常炫酷,推薦給小伙伴們。2015-02-02
uniapp項(xiàng)目?jī)?yōu)化方式及建議
性能優(yōu)化自古以來(lái)就是重中之重,本文關(guān)于uniapp項(xiàng)目?jī)?yōu)化方式最全整理,會(huì)根據(jù)開(kāi)發(fā)情況進(jìn)行補(bǔ)充,感興趣的可以了解一下2021-08-08
javascript實(shí)現(xiàn)的一個(gè)帶下拉框功能的文本框
這篇文章主要介紹了javascript實(shí)現(xiàn)的一個(gè)帶下拉框功能的文本框,需要的朋友可以參考下2014-05-05
js實(shí)現(xiàn)鼠標(biāo)滑過(guò)文字鏈接色彩變化的效果
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)滑過(guò)文字鏈接色彩變化的效果,涉及javascript鼠標(biāo)事件及樣式操作的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05
史上最全JavaScript數(shù)組去重的十種方法(推薦)
這篇文章主要介紹了JavaScript數(shù)組去重的十種方法,利用元素的屬性和特性進(jìn)行不同的去重方法,并實(shí)例演示如何測(cè)試去重超大數(shù)組,具體操作步驟大家可查看下文的詳細(xì)講解,感興趣的小伙伴們可以參考一下。2017-08-08
僅Firefox中鏈接A無(wú)法實(shí)現(xiàn)模擬點(diǎn)擊以觸發(fā)其默認(rèn)行為
偶然發(fā)現(xiàn)之前寫(xiě)的事件模塊在Firefox5中無(wú)法觸發(fā)A的默認(rèn)行為了。IE/Opera/Firefox5中A具有click方法,因此模擬點(diǎn)擊直接調(diào)用click方法即可。2011-07-07
javascript加號(hào)"+"的二義性說(shuō)明
單個(gè)的加號(hào)作為運(yùn)算符在 JavaScript 中有三種作用。2013-03-03

