Ajax是常用的一門與Web服務(wù)器通信的技術(shù),目前發(fā)送Ajax請求的主要有4種方式:
至于原生的XHR目前工作中已經(jīng)很少去手寫它了,前些年我們比較常用的是jquery的ajax請求,但是近些年前端發(fā)展很快,jquery包裝的ajax已經(jīng)失去了往日的光輝,取而代之的是新出現(xiàn)的axios和fetch,兩者都開始搶占“請求”這個(gè)前端重要領(lǐng)域。本文結(jié)合自己的使用經(jīng)歷總結(jié)一下它們之間的一些區(qū)別,并給出一些自己的理解。 1.Jquery ajax代碼示例: $.ajax({ type:'GET', url:url, data:data, dataType:dataType success:function(){}, error:function(){}}) 以上代碼很簡單,我就不多解釋了,這就是jquery對原生XHR的封裝,另外還增加了jsonp的支持,讓ajax請求可以支持跨域請求,但是要注意的是:jsonp請求本質(zhì)不是XHR異步請求,就是請求了一個(gè)js文件,因此在瀏覽器的network面板中的xhr標(biāo)簽下看不到j(luò)sonp的跨域請求,但是在js標(biāo)簽下能看見。 jsonp請求示例: <!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>使用jQuery-AJAX--讀取獲得跨域JSONP數(shù)據(jù)</title> <script src='./jquery-1.7.2.js' type='text/javascript'></script> <style type='text/css'> body,html{font-family: 'Microsoft Yahei';} a{text-decoration: none;} </style></head><body><h2><a href='javascript:void(0)' class='btnAJAX'>點(diǎn)擊AJAX獲取數(shù)據(jù)JSONP跨域....</a></h2><script src='jquery.min.js'></script><script type='text/javascript'> $(function() { $('.btnAJAX').click(function(){ $.ajax({ type : 'get', async:false, url : 'http://weather.123./static/weather_info/101121301.html', dataType : 'jsonp', jsonp: '', //服務(wù)端用于接收callback調(diào)用的function名的參數(shù) jsonpCallback:'weather_callback', //callback的function名稱 success : function(json){ console.log(json); //瀏覽器調(diào)試的時(shí)候用 }, error:function(){ alert('fail'); } }); }); });</script></body></html> 效果如下: 當(dāng)點(diǎn)擊以上文字時(shí),查看xhr請求,發(fā)現(xiàn)并沒有發(fā)出xhr請求 再查看js請求,發(fā)現(xiàn)js發(fā)出了一個(gè)請求,因此jsonp本質(zhì)是js請求而并非xhr 請求,只是$.ajax把jsonp請求封裝到了ajax里面而已。 其實(shí)jquery ajax使用起來已經(jīng)是很方便了,那為什么現(xiàn)在還會(huì)被慢慢拋棄呢?個(gè)人認(rèn)為主要原因有以下幾點(diǎn):
總結(jié) 隨著前端基于MVVM模式的Vue和React新一代框架的興起,以及ES6等新規(guī)范的制定,像Jquery這種大而全的JS庫注定是要走向低潮的。 2.Axios代碼示例: axios({ method: 'post', url: '/login', data: { username:'martin', password:'a1234567' }}).then(function (res) { console.log(res);}).catch(function (err) { console.log(err);}); 這種ajax請求方式是Vue框架的作者尤雨溪開始推薦使用的。其實(shí)Axios的本質(zhì)也是基于原生XHR的封裝,只不過它是基于ES6的新語法Promise的實(shí)現(xiàn)版本。并且具有以下幾條特性:
總結(jié) Axios除了和jquery ajax一樣封裝了原生的XHR,還提供了很多比如:并發(fā)請求、攔截等多種接口,同時(shí)它的體積還比較小,也沒有下文fetch的各種問題,可以說是目前最佳的ajax請求方式了。 3.Fetch代碼示例: try{ var response=await fetch(url); var data=response.json(); console.log(data);}catch(e){ console.log('error is'+e); } 上面說的$.ajax和Axios說到底本質(zhì)都是對原生XHR的封裝,但是Fetch可以說是新時(shí)代XHR的替代品。它的特性如下:
但是目前Fetch還存在很多問題 1)fetch只對網(wǎng)絡(luò)請求報(bào)錯(cuò),對400,500都當(dāng)做成功的請求 2)fetch默認(rèn)不會(huì)帶cookie,需要添加配置項(xiàng) 3)fetch沒有辦法原生監(jiān)測請求的進(jìn)度,而XHR可以 Fetch在使用上說實(shí)話目前還沒有axios和jquery ajax方便,因此我個(gè)人在工作中也是使用axios的比較多。說到這里,你可能覺得Fetch就是強(qiáng)行用ES新規(guī)范做出來的代替XHR的半成品,事實(shí)上我就是這么認(rèn)為的。但是有一點(diǎn)Fetch做的性能要遠(yuǎn)比XHR要好,那就是“跨域的處理”。 因?yàn)橥床呗缘募s束,瀏覽器發(fā)送的請求是不能隨便跨域的,一定要借助JSONP或者跨域頭來協(xié)助跨域,而Fetch可以直接設(shè)置mode為“no-cors”來實(shí)現(xiàn)跨域訪問,如下所示 fetch('/login.json', { method: 'post', mode: 'cors', data: {name:martin''}}).then(function() { /* handle response */ }); 我們會(huì)得到一個(gè)type為“opaque”(透明)的response。這個(gè)請求是真正抵達(dá)過后臺的,但是瀏覽器不可以訪問返回的內(nèi)容,這也就是為什么response中的type為“opaque”(透明)的原因。 總結(jié) Fetch還是一個(gè)新時(shí)代的半成品,很多地方并不完善,但是也有它的優(yōu)勢所在,總的來說,就是Fetch技術(shù)還需要時(shí)間的沉淀,目前還沒有達(dá)到axios的性能。 4.大總結(jié)如果你是直接拉到底部的,就只要記住這個(gè)結(jié)論就可以啦,目前只需要熟練使用Axios就可以啦,Jquery的ajax會(huì)逐漸被時(shí)代淘汰,F(xiàn)etch雖然符合前端潮流,但是目前還尚不成熟,沒有Axios使用起來便利。 |
|