從事前端也有段時間了,發送請求也是家常便飯,最近接手一個項目,出現用fetch會有未知bug產生,當我換成Axios以后就好了,所以就打算捋一下Ajax、Axios和Fetch,也算讓自己更了解一下自己從事的工作吧。
簡介
Ajax
AJAX(Asynchronous JavaScript and XML),指的是一套綜合了多項技術的瀏覽器端網頁開發技術。Ajax的概念由杰西·詹姆士·賈瑞特所提出。我個人理解就是頁面有數據變化不用整個頁面刷新,而是可以進行異步請求再通過JS進行數據更換。在現代瀏覽器上寫AJAX主要依靠XMLHttpRequest對象。
Axios
可以把Promise用在node和HTTP客戶端
Fetch
提供了一個 JavaScript接口,用于訪問和操縱HTTP管道的部分,例如請求和響應。它還提供了一個全局fetch()
方法,該方法提供了一種簡單,合理的方式來跨網絡異步獲取資源。
兼容性
Ajax
Fetch
- Supported 支持
- Not supported 不支持
- Partial support 部分支持
- Support unknown 支持情況未知
Axios
總結
我們不看Axios這個庫,但就Ajax和fetch這兩個,Ajax的兼容性要好于Fetch,Axios的兼容性我覺得首先取決于Ajax的兼容性,其次是取決于開發者的適配了,所以我覺得兼容性方面是Fetch<Axios<Ajax
實現
Ajax
var xmlhttp;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行代碼
xmlhttp=new XMLHttpRequest();
} else {
// IE6, IE5 瀏覽器執行代碼
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","url",true);
xmlhttp.send();
從這我們就能看出來,原生的Ajax很不好理解,甚至有的面試官在面試的時候會讓我們手寫Ajax請求,我覺得Ajax請求原理我們做前端的是一點要知道的,但是,我們在工作中不能這些,一是不方便,二是很容易出錯,所以我們可以選擇JQ來幫助我們
jQuery Ajax
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function() {},
error: function() {}
})
從JQ封裝好的Ajax請求來看,結構清晰,簡單明了,并且JQ已經幫我們處理好了兼容性的問題,所以我們可以大膽的使用,但是有一點,如果你只是為了一個Ajax而引用一個jQuery庫的話,未壓縮的有266kb,壓縮以后也有86kb,顯然有點小題大做,殺雞焉用宰牛刀。
Axios
const axios = require('axios');
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Axios的結構也很明了,并且引入了Promise,在處理上沒有了回調地獄,在錯誤處理上也使用了.catch()
,可以說是相當方便了
Fetch
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
這么看來的話,貌似Fetch的使用也很清晰,但是我們往下看
對比
在此使用jQuery Ajax還代替原生Ajax來參加比賽;
jQuery Ajax在經過jQuery近十來年的更新維護,已經可以說使用非常方便,在便捷性、兼容性和使用上差不多沒什么可以挑剔了,But
- 本身是針對MVC的編程,不符合現在前端MVVM的浪潮
- 基于原生的XHR開發,XHR本身的架構不清晰,已經有了fetch的替代方案
- JQuery整個項目太大,單純使用ajax卻要引入整個JQuery非常的不合理(采取個性化打包的方案又不能享受CDN服務)
雖然jQuery在前端領域經理過輝煌,現在也不乏“老夫只用jQuery”的梗來調侃jQuery的過時,但是它的成功是不可否定的,可沒有跟上前端快速發展的步伐,就像諾基亞一樣,什么都沒有做錯,但這就是唯一做錯的地方,一代巨人也會倒下
Aioxs雖然本質上也是對XHR的高級封裝,并支持了Promise,符合最新的ECMA規范,就github上的介紹:
- Make XMLHttpRequests from the browser // 可以從瀏覽器發起XHR請求
- Make http requests from node.js // 從 node.js 創建 http 請求
- Supports the Promise API // 支持Promise API
- Intercept request and response // 攔截請求和響應
- Transform request and response data // 轉換請求和響應數據
- Cancel requests // 取消請求
- Automatic transforms for JSON data // 自動轉換JSON數據
- Client side support for protecting against XSRF // 支持客戶端防止XSRF攻擊
Axios也完成了各種封裝,并且大小也只有4.5kb,已經很小了,并且還有并發的封裝,現在看來Axios是個不錯的選擇;
由于Fetch API是基于Promise設計,舊瀏覽器不支持Promise,并且Fetch比較偏底層,相對于Axios和jQuery Ajax來說,沒有過多的封裝,在使用上自然沒有他們方便,而且沒有封裝過的Fetch還有很多不足之處
- Fetch默認不攜帶cookie信息,需要設置
credentials: 'include'
- 服務器返回 400,500 錯誤碼時并不會 reject,只有網絡錯誤這些導致請求不能完成時,fetch 才會被 reject
- 因為Fetch基于Promise,所以會有很多Promise的未知bug
但是Fetch得優點依然會有:
- 脫離了XHR,是ES規范里新的實現方式
- 更加底層,提供的API豐富(request, response)
- 符合關注分離,沒有將輸入、輸出和用事件來跟蹤的狀態混雜在一個對象里
- 更好更方便的寫法
總結
Ajax雖然年老,但是用他肯定不會有兼容性的問題,可jQuery太大,貌似會拖累前端前進的步伐。而Fetch尚還年輕,大環境對他來說可以生存,可不能很好的生活下去,但以后肯定會發光發熱,未來是屬于Fetch的。現在我們大可以放心使用Axios,成熟,輕量,API簡單,正當年的時候,用他準沒錯。
本文帶有個人偏見,不對的地方請指正
參考
《傳統 Ajax 已死,Fetch 永生》
《Jquery ajax, Axios, Fetch區別之我見》
《Fetch vs Axios http request》