Ajax語法淺析

 

Ajax是目前很廣泛的一門技術,也是很值得探討和研究的一門技術。本文將針對Ajax的發展過程並結合其在不一樣庫框架中的使用方式來和你們分享下Ajax的那些新老語法。php

Ajax簡介

Ajax全稱爲「Asynchronous Javascript And XML」, 即「異步JavaScript和XML」的意思。經過Ajax咱們能夠向服務器發送請,在不阻塞頁面的狀況下進行數據交互,也能夠理解爲異步數據傳輸。在Ajax的幫助下咱們的網頁只需局部刷新便可更新數據的顯示,減小了沒必要要的數據量,大大提升了用戶體驗,縮短了用戶等待的時間,使得web應用程序更小、更快,更友好。html

固然以上都是司空見慣的內容了,做爲一名合格的開發人員基本都再熟悉不過了,這裏只爲那些剛入門的新手作一個簡單的介紹。更多的關於Ajax的簡介請移步W3School進行了解:http://www.w3school.com.cn/php/php_ajax_intro.asp前端

原生Ajax

基本上全部現代的瀏覽器都支持原生Ajax的功能,下面就來詳細介紹下利用原生JS咱們怎樣來發起和處理Ajax請求。vue

1.獲取XMLHttpRequest對象

var xhr = new XMLHttpRequest(); // 獲取瀏覽器內置的XMLHttpRequest對象

若是你的項目應用不考慮低版本IE,那麼能夠直接用上面的方法,全部現代瀏覽器 (Firefox、Chrome、Safari 以及 Opera) 都內建了 XMLHttpRequest 對象。若是須要兼容老版本IE(IE五、IE6),那麼可使用 ActiveX 對象:jquery

複製代碼
var xhr;

if (window.XMLHttpRequest) {
    xhr=new XMLHttpRequest();
} else if (window.ActiveXObject) {    // 兼容老版本瀏覽器
    xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
複製代碼

2.參數配置

有了XMLHttpRequest對象,咱們還須要配置一些請求的參數信息來完成數據交互,利用open方法便可:git

複製代碼
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。angularjs

3.發送請求

配置完了基本參數信息,咱們直接調用send方法發送請求,代碼以下:es6

複製代碼
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方法裏,如:github

xhr.open('POST', '/test/', true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 將請求頭設置爲表單方式提交
xhr.send('name=luozh&size=12');

最終會以Form Data的形式傳遞:web

圖片描述

 

若是不設置請求頭,原生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(可能須要FQ)

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的詳細介紹能夠移步:http://www.javashuo.com/article/p-cqggfgkp-ec.html

跨域Ajax

介紹了各類各樣的Ajax API,咱們不能避免的一個重要問題就是跨域,這裏重點講解下Ajax跨域的處理方式。

處理Ajax跨域問題主要有如下4種方式:

  1. 利用iframe

  2. 利用JSONP

  3. 利用代理

  4. 利用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的概念和流程,即可以輕鬆的在數據異步交互的時代遊刃有餘。

 

原創文章,轉載請註明來自 勞卜 - 博客園[http://www.cnblogs.com/luozhihao] 

本文地址:http://www.cnblogs.com/luozhihao/p/5846925.html

本文同步發表於:

segmentfault:http://www.javashuo.com/article/p-cpsqmnqw-hm.html

微信公衆號「前端呼啦圈」(Love-FED)

相關文章
相關標籤/搜索