Ajax語法淺析
Ajax是目前很普遍的一門技術,也是很值得探討和研究的一門技術。本文將針對Ajax的發展過程並結合其在不同庫框架中的使用方式來和大家分享下Ajax的那些新老語法。
Ajax簡介
Ajax全稱為“Asynchronous Javascript And XML”, 即“非同步JavaScript和XML”的意思。通過Ajax我們可以向伺服器傳送請求,在不阻塞頁面的情況下進行資料互動,也可以理解為非同步資料傳輸。在Ajax的幫助下我們的網頁只需區域性重新整理即可更新資料的顯示,減少了不必要的資料量,大大提高了使用者體驗,縮短了使用者等待的時間,使得web應用程式更小、更快,更友好。
當然以上都是司空見慣的內容了,作為一名合格的開發人員基本都再熟悉不過了,這裡只為那些剛入門的新手做一個簡單的介紹。更多的關於Ajax的簡介請移步W3School進行了解:http://www.w3school.com.cn/php/php_ajax_intro.asp
原生Ajax
基本上所有現代的瀏覽器都支援原生Ajax的功能,下面就來詳細介紹下利用原生JS我們怎樣來發起和處理Ajax請求。
1.獲取XMLHttpRequest物件
var xhr = new XMLHttpRequest(); // 獲取瀏覽器內建的XMLHttpRequest物件
如果你的專案應用不考慮低版本IE,那麼可以直接用上面的方法,所有現代瀏覽器 (Firefox、Chrome、Safari 以及 Opera) 都內建了 XMLHttpRequest 物件。如果需要相容老版本IE(IE5、IE6),那麼可以使用 ActiveX 物件:
var xhr; if (window.XMLHttpRequest) { xhr=new XMLHttpRequest(); } else if (window.ActiveXObject) { // 相容老版本瀏覽器 xhr=new ActiveXObject("Microsoft.XMLHTTP"); }
2.引數配置
有了XMLHttpRequest物件,我們還需要配置一些請求的引數資訊來完成資料互動,利用open方法即可:
var xhr; if (window.XMLHttpRequest) { xhr=new XMLHttpRequest(); } else if (window.ActiveXObject) { xhr=new ActiveXObject("Microsoft.XMLHTTP"); } if (xhr) { xhr.open('GET', '/test/', true); // 以GET請求的方式向'/test/'路徑傳送非同步請求 }
open方法為我們建立了一個新的http請求,其中第一個引數為請求方式,一般為'GET'或'POST';第二個引數為請求url;第三個引數為是否非同步,預設為true。
3.傳送請求
配置完了基本引數資訊,我們直接呼叫send方法傳送請求,程式碼如下:
var xhr; if (window.XMLHttpRequest) { xhr=new XMLHttpRequest(); } else if (window.ActiveXObject) { xhr=new ActiveXObject("Microsoft.XMLHTTP"); } if (xhr) { xhr.open('GET', '/test/', true); xhr.send(); // 呼叫send方法傳送請求 }
這裡需要注意的是如果使用GET方法傳遞引數,我們可以直接將引數放在url後面,比如'/test/?name=luozh&size=12';如果使用POST方法,那麼我們的引數需要寫在send方法裡,如:
xhr.open('POST', '/test/', true); xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 將請求頭設定為表單方式提交 xhr.send('name=luozh&size=12');
最終會以Form Data的形式傳遞:
如果不設定請求頭,原生Ajax會預設使用Content-Type是'text/plain;charset=UTF-8'的方式傳送資料,如果按照上面的引數書寫形式,我們最終傳輸的形式這樣的:
顯然這並不是伺服器期望的資料格式,我們可以這樣寫:
xhr.open('POST', '/test/', true); xhr.send(JSON.stringify({name: 'luozh', size: 12}));
最終傳輸的格式如下:
這樣我們可以直接傳遞JSON字串給後臺處理,當然後臺也許進行相應配置。
4.監測狀態
傳送完Ajax請求之後,我們需要針對伺服器返回的狀態進行監測並進行相應的處理,這裡我們需要使用onreadystatechange方法,程式碼如下:
var xhr; if (window.XMLHttpRequest) { xhr=new XMLHttpRequest(); } else if (window.ActiveXObject) { xhr=new ActiveXObject("Microsoft.XMLHTTP"); } if (xhr) { xhr.open('GET', '/test/', true); // 以GET請求的方式向'/test/'路徑傳送非同步請求 xhr.send(); xhr.onreadystatechange = function () { // 利用onreadystatechange監測狀態 if (xhr.readyState === 4) { // readyState為4表示請求響應完成 if (xhr.status === 200) { // status為200表示請求成功 console.log('執行成功'); } else { console.log('執行出錯'); } } } }
上面我們利用onreadystatechange監測狀態,並在內部利用readyState獲取當前的狀態。readyState一共有5個階段,當其為4時表示響應內容解析完成,可以在客戶端呼叫了。當readyState為4時,我們又通過status來獲取狀態碼,狀態碼為200時執行成功程式碼,否則執行出錯程式碼。
當然我們可以用onload來代替onreadystatechange等於4的情況,因為onload只在狀態為4的時候才被呼叫,程式碼如下:
xhr.onload = function () { // 呼叫onload if (xhr.status === 200) { // status為200表示請求成功 console.log('執行成功'); } else { console.log('執行出錯'); } }
然而需要注意的是,IE對onload這個屬性的支援並不友好。
除了onload還有
-
onloadstart
-
onprogress
-
onabort
-
ontimeout
-
onerror
-
onloadend
等事件,有興趣的同學可以親自去實踐它們的用處。
以上便是原生Ajax請求資料的常見程式碼。
其他庫框架中的Ajax
1.jQuery中的Ajax
jQuery作為一個使用人數最多的庫,其Ajax很好的封裝了原生Ajax的程式碼,在相容性和易用性方面都做了很大的提高,讓Ajax的呼叫變得非常簡單。下面便是一段簡單的jQuery的Ajax程式碼:
$.ajax({ method: 'GET', // 1.9.0本版前用'type' url: "/test/", dataType: 'json' }) .done(function() { console.log('執行成功'); }) .fail(function() { console.log('執行出錯'); })
與原生Ajax不同的是,jQuery中預設的Content-type是'application/x-www-form-urlencoded; charset=UTF-8', 想了解更多的jQuery Ajax的資訊可以移步官方文件:http://api.jquery.com/jquery.ajax
2.Vue.js中的Ajax
Vue.js作為目前熱門的前端框架,其實其本身並不包含Ajax功能,而是通過外掛的形式額外需要在專案中引用,其官方推薦Ajax外掛為vue-resource,下面便是vue-resource的請求程式碼:
Vue.http.get('/test/').then((response) => { console.log('執行成功'); }, (response) => { console.log('執行出錯'); });
vue-resource支援Promise API,同時支援目前的Firefox, Chrome, Safari, Opera 和 IE9+瀏覽器,在瀏覽器相容性上不相容IE8,畢竟Vue本身也不相容IE8。想了解更多的vue-resource的資訊可以移步github文件:https://github.com/vuejs/vue-resource
3.Angular.js中的Ajax
這裡Angular.js中的Ajax主要指Angular的1.×版本,因為Angular2目前還不建議在生產環境中使用。
var myApp = angular.module('myApp',[]); var myCtrl = myApp.controller('myCtrl',['$scope','$http',function($scope, $http){ $http({ method: 'GET', url: '/test/', headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'} }).success(function (data) { console.log('執行成功'); }).error(function () { console.log('執行出錯'); }); }]);
在Angular中,我們需要在控制器上註冊一個$http的事件,然後才能在內部執行Ajax。Angular的Ajax預設的Content-type是'application/json;charset=UTF-8',所以如果想用表單的方式提交還需設定下headers屬性。想了解更多的Angular Ajax的資訊可以移步官方文件:https://docs.angularjs.org/api/ng/service/$http(可能需要翻牆)更多精彩內容關注微信公眾號:全棧開發者中心(admin10000_com)
4.React中的Ajax
在React中我比較推薦使用fetch來請求資料,當然其不僅適用於React,在任何一種框架如上面的Vue、Angular中都可以使用,因為其已經被目前主流瀏覽器所支援,至於其主要功能和用法,我在下面會做下講解。
Fetch API
Fetch API 是基於 Promise 設計,由於Promise的瀏覽器相容性問題及Fetch API本身的相容問題,一些瀏覽器暫時不支援Fetch API,瀏覽器相容圖如下:
當然我們可以通過使用一些外掛來解決相容性問題,比如:fetch-polyfill、es6-promise、fetch-ie8等。
使用Fetch我們可以非常便捷的編寫Ajax請求,我們用原生的XMLHttpRequst物件和Fetch來比較一下:
XMLHttpRequst API
// XMLHttpRequst API var xhr = new XMLHttpRequest(); xhr.open('GET', '/test/', true); xhr.onload = function() { console.log('執行成功'); }; xhr.onerror = function() { console.log('執行出錯'); }; xhr.send();
Fetch API
fetch('/test/').then(function(response) { return response.json(); }).then(function(data) { console.log('執行成功'); }).catch(function(e) { console.log('執行出錯'); });
可以看出使用Fetch後我們的程式碼更加簡潔和語義化,鏈式呼叫的方式也使其更加流暢和清晰。隨著瀏覽器核心的不斷完善,今後的XMLHttpRequest會逐漸被Fetch替代。關於Fetch的詳細介紹可以移步:https://segmentfault.com/a/1190000003810652
跨域Ajax
介紹了各種各樣的Ajax API,我們不能避免的一個重要問題就是跨域,這裡重點講解下Ajax跨域的處理方式。
處理Ajax跨域問題主要有以下4種方式:
-
利用iframe
-
利用JSONP
-
利用代理
-
利用HTML5提供的XMLHttpRequest Level2
第1和第2種方式大家應該都非常熟悉,都屬於前端的活,這裡就不做介紹了,這裡主要介紹第3和第4種方式。
利用代理的方式可以這樣理解:
通過在同域名下的web伺服器端建立一個代理:
北京伺服器(域名:www.beijing.com)
上海伺服器(域名:www.shanghai.com)
比如在北京的web伺服器的後臺(www.beijing.com/proxy-shanghaiservice.php)來呼叫上海伺服器(www.shanghai.com/services.php)的服務,然後再把訪問結果返回給前端,這樣前端呼叫北京同域名的服務就和呼叫上海的服務效果相同了。
利用XMLHttpRequest Level2的方式需要後臺將請求頭進行相應配置:
// php語法
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET,POST');
以上的*號可以替換成允許訪問的域名,*表示所有域名都可以訪問。
由此可見,第3和第4種方式主要是後臺的活,前端只需呼叫就可以。
總結
無論Ajax的語法多麼多變,無論庫和框架如何封裝Ajax,其只是一種實現非同步資料互動的工具,我們只需理解原生JS中Ajax的實現原理,瞭解XMLHttpRequest及promise的概念和流程,便可以輕鬆的在資料非同步互動的時代遊刃有餘。
相關文章
- Ajax 什麼是Ajax? Ajax的基本語法
- 通過 PHP 與 Python 程式碼對比淺析語法差異PHPPython
- 通過PHP與Python程式碼對比淺析語法差異PHPPython
- Julia1.0程式語言淺析
- C語言巨集和函式淺析C語言函式
- C語言有關函式淺析C語言函式
- 淺談Kotlin語法篇之基礎語法(一)Kotlin
- iOS Block淺淺析iOSBloC
- [專業術語]淺析當代 LBS 技術
- MySQL 查詢語句執行過程淺析MySql
- RunLoop 淺析OOP
- 淺析 ReentrantLockReentrantLock
- Unstated淺析
- 淺析SharedPreferences
- Nginx淺析Nginx
- 淺析PromisePromise
- ejs 淺析JS
- 淺析KubernetesStatefulSet
- AIDL淺析AI
- MongoDB淺析MongoDB
- 淺析 JWTJWT
- 淺析RedisRedis
- Jvm 淺析JVM
- ArrayList淺析
- CGLib淺析CGLib
- 淺析XMLXML
- 淺析 DDD
- 淺析MySQL語句優化中的explain引數MySql優化AI
- koa原理淺析
- 淺析 React FiberReact
- HTTP Cache 淺析HTTP
- BTrace 原理淺析
- HashMap之淺析HashMap
- setXfermode 模式淺析模式
- 比特幣淺析比特幣
- Seata原理淺析
- 淺析AIGC for MMKGAIGC
- shadow DOM 淺析
- 淺析Promise原理Promise