一.簡介 對於WEB應用程式:用戶瀏覽器發送請求,伺服器接收並處理請求,然後返回結果,往往返回就是字元串(HTML),瀏覽器將字元串(HTML)渲染並顯示瀏覽器上 通過在後臺與伺服器進行少量數據交換,AJAX 可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新 ...
一.簡介
對於WEB應用程式:用戶瀏覽器發送請求,伺服器接收並處理請求,然後返回結果,往往返回就是字元串(HTML),瀏覽器將字元串(HTML)渲染並顯示瀏覽器上
通過在後臺與伺服器進行少量數據交換,AJAX 可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新
AJAX,Asynchronous JavaScript and XML (非同步的JavaScript和XML),一種創建互動式網頁應用的網頁開發技術方案。
- 非同步的JavaScript:
使用 【JavaScript語言】 以及 相關【瀏覽器提供類庫】 的功能向服務端發送請求,當服務端處理完請求之後,【自動執行某個JavaScript的回調函數】。
PS:以上請求和響應的整個過程是【偷偷】進行的,頁面上無任何感知。 - XML
XML是一種標記語言,是Ajax在和後臺交互時傳輸數據的格式之一
利用AJAX可以做:
- 註冊時,輸入用戶名自動檢測用戶是否已經存在。
- 登陸時,提示用戶名密碼錯誤
- 刪除數據行時,將行ID發送到後臺,後臺在資料庫中刪除,資料庫刪除成功後,在頁面DOM中將數據行也刪除
二.偽Ajax
由於HTML標簽的iframe標簽具有局部載入內容的特性,所以可以使用其來偽造Ajax請求
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <div> <p>請輸入要載入的地址:<span id="currentTime"></span></p> <p> <input id="url" type="text" /> <input type="button" value="刷新" onclick="LoadPage();"> </p> </div> <div> <h3>載入頁面位置:</h3> <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe> </div> <script type="text/javascript"> window.onload= function(){ var myDate = new Date(); document.getElementById('currentTime').innerText = myDate.getTime(); }; function LoadPage(){ var targetUrl = document.getElementById('url').value; document.getElementById("iframePosition").src = targetUrl; } </script> </body> </html>View Code
三.原生Ajax
Ajax主要就是使用 【XmlHttpRequest】對象來完成請求的操作,該對象在主流瀏覽器中均存在(除早起的IE),Ajax首次出現IE5.5中存在(ActiveX控制項)。
1、XmlHttpRequest對象介紹
XmlHttpRequest對象的主要方法:
a. void open(String method,String url,Boolen async)
用於創建請求
參數:
method: 請求方式(字元串類型),如:POST、GET、DELETE...
url: 要請求的地址(字元串類型)
async: 是否非同步(布爾類型)
b. void send(String body)
用於發送請求
參數:
body: 要發送的數據(字元串類型)
c. void setRequestHeader(String header,String value)
用於設置請求頭
參數:
header: 請求頭的key(字元串類型)
vlaue: 請求頭的value(字元串類型)
d. String getAllResponseHeaders()
獲取所有響應頭
返回值:
響應頭數據(字元串類型)
e. String getResponseHeader(String header)
獲取響應頭中指定header的值
參數:
header: 響應頭的key(字元串類型)
返回值:
響應頭中指定的header對應的值
f. void abort()
終止請求
XmlHttpRequest對象的主要方法
XmlHttpRequest對象的主要屬性:
a. Number readyState
狀態值(整數)
詳細:
0-未初始化,尚未調用open()方法;
1-啟動,調用了open()方法,未調用send()方法;
2-發送,已經調用了send()方法,未接收到響應;
3-接收,已經接收到部分響應數據;
4-完成,已經接收到全部響應數據;
b. Function onreadystatechange
當readyState的值改變時自動觸發執行其對應的函數(回調函數)
c. String responseText
伺服器返回的數據(字元串類型)
d. XmlDocument responseXML
伺服器返回的數據(Xml對象)
e. Number states
狀態碼(整數),如:200、404...
f. String statesText
狀態文本(字元串),如:OK、NotFound...
View Code
2、跨瀏覽器支持
- XmlHttpRequest
IE7+, Firefox, Chrome, Opera, etc. - ActiveXObject("Microsoft.XMLHTTP")
IE6, IE5
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <h1>XMLHttpRequest - Ajax請求</h1> <input type="button" onclick="XmlGetRequest();" value="Get發送請求" /> <input type="button" onclick="XmlPostRequest();" value="Post發送請求" /> <script src="/statics/jquery-1.12.4.js"></script> <script type="text/javascript"> function GetXHR(){ var xhr = null; if(XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); } return xhr; } function XhrPostRequest(){ var xhr = GetXHR(); // 定義回調函數 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已經接收到全部響應數據,執行以下操作 var data = xhr.responseText; console.log(data); } }; // 指定連接方式和地址----文件方式 xhr.open('POST', "/test/", true); // 設置請求頭 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); // 發送請求 xhr.send('n1=1;n2=2;'); } function XhrGetRequest(){ var xhr = GetXHR(); // 定義回調函數 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已經接收到全部響應數據,執行以下操作 var data = xhr.responseText; console.log(data); } }; // 指定連接方式和地址----文件方式 xhr.open('get', "/test/", true); // 發送請求 xhr.send(); } </script> </body> </html>基於原生AJAX - Demo
四.jQuery Ajax
jQuery其實就是一個JavaScript的類庫,其將複雜的功能做了上層封裝,使得開發者可以在其基礎上寫更少的代碼實現更多的功能。
- jQuery 不是生產者,而是大自然搬運工。
- jQuery Ajax本質 XMLHttpRequest 或 ActiveXObject
註:2.+版本不再支持IE9以下的瀏覽器
jQuery.get(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
dataType: 返回內容格式,xml, json, script, text, html
jQuery.post(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數
success: 載入成功時回調函數
dataType: 返回內容格式,xml, json, script, text, html
jQuery.getJSON(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
jQuery.getScript(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
jQuery.ajax(...)
部分參數:
url:請求地址
type:請求方式,GET、POST(1.9.0之後用method)
headers:請求頭
data:要發送的數據
contentType:即將發送信息至伺服器的內容編碼類型(預設: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否非同步
timeout:設置請求超時時間(毫秒)
beforeSend:發送請求前執行的函數(全局)
complete:完成之後執行的回調函數(全局)
success:成功之後執行的回調函數(全局)
error:失敗之後執行的回調函數(全局)
accepts:通過請求頭髮送給伺服器,告訴伺服器當前客戶端課接受的數據類型
dataType:將伺服器端返回的數據轉換成指定類型
"xml": 將伺服器端返回的內容轉換成xml格式
"text": 將伺服器端返回的內容轉換成普通文本格式
"html": 將伺服器端返回的內容轉換成普通文本格式,在插入DOM中時,如果包含JavaScript標簽,則會嘗試去執行。
"script": 嘗試將返回值當作JavaScript去執行,然後再將伺服器端返回的內容轉換成普通文本格式
"json": 將伺服器端返回的內容轉換成相應的JavaScript對象
"jsonp": JSONP 格式
使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數
如果不指定,jQuery 將自動根據HTTP包MIME信息返回相應類型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
converters: 轉換器,將伺服器端的內容根據指定的dataType轉換類型,並傳值給success回調函數
$.ajax({
accepts: {
mycustomtype: 'application/x-some-custom-type'
},
// Expect a `mycustomtype` back from server
dataType: 'mycustomtype'
// Instructions for how to deserialize a `mycustomtype`
converters: {
'text mycustomtype': function(result) {
// Do Stuff
return newresult;
}
},
});
jQuery Ajax 方法列表
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <p> <input type="button" onclick="XmlSendRequest();" value='Ajax請求' /> </p> <script type="text/javascript" src="jquery-1.12.4.js"></script> <script> function JqSendRequest(){ $.ajax({ url: "http://c2.com:8000/test/", type: 'GET', dataType: 'text', success: function(data, statusText, xmlHttpRequest){ console.log(data); } }) } </script> </body> </html>基於jQueryAjax - Demo
例:
保存伺服器,成功時將結果顯示到HTML頁面
$.ajax({
url: "test.html",
cache: false,
success: function(html){
$("#results").append(html);
}
});
保存數據到伺服器,成功時顯示信息
$.ajax({
type: "POST",
url: "/index",
data: "name=John&location=Boston",
success: function(msg){
alert( "Data Saved: " + msg );
}
});
jQuery.get(url, [data], [callback], [type]),通過遠程 HTTP GET 請求載入信息
參數;
rl,[data],[callback],[type]String,Map,Function,String url:待載入頁面的URL地址 data:待發送 Key/value 參數。 callback:載入成功時回調函數。 type:返回內容格式,xml, html, script, json, text, _default。
例:
//請求 www.test.com 網頁,忽略返回值 $.get("www.test.com");
//請求 test.php 網頁,傳送2個參數,忽略返回值 $.get("test.php", { name: "John", time: "2pm" } );
//顯示 test.php 返回值(HTML 或 XML,取決於返回值) $.get("test.php", function(data){ alert("Data Loaded: " + data); });
//顯示 test.cgi 返回值(HTML 或 XML,取決於返回值),添加一組請求參數 $.get("test.cgi", { name: "John", time: "2pm" }, function(data){ alert("Data Loaded: " + data); });
jQuery.post(url, [data], [callback], [type])
概述(常用)
通過遠程 HTTP POST 請求載入信息。
這是一個簡單的 POST 請求功能以取代複雜 $.ajax 。請求成功時可調用回調函數。如果需要在出錯時執行函數,請使用 $.ajax。
參數:
url,[data],[callback],[type]String,Map,Function,String url: //發送請求地址。 data: //待發送 Key/value 參數。 callback: //發送成功時回調函數。 type: //返回內容格式,xml, html, script, json, text, _default。
例:
//請求 test.php 網頁,忽略返回值 $.post("test.php");
//請求 test.php 頁面,並一起發送一些額外的數據(同時仍然忽略返回值) $.post("test.php", { name: "John", time: "2pm" } );
//向伺服器傳遞數據數組(同時仍然忽略返回值): $.post("test.php", { 'choices[]': ["Jon", "Susan"] });
//輸出來自請求頁面 test.php 的結果(HTML 或 XML,取決於所返回的內容) $.post("test.php", function(data){ alert("Data Loaded: " + data); });
//向頁面 test.php 發送數據,並輸出結果(HTML 或 XML,取決於所返回的內容) $.post("test.php", { name: "John", time: "2pm" }, function(data){ alert("Data Loaded: " + data); });
//jQuery 1.12 中 jQuery.post支持對象參數 $.post({ url: "/csrf", data:{"k1": "v1", "_xsrf": nid}, success:function (callback) { callback="cs"; console.log(callback); } });
4.2 Ajax 事件
ajaxComplete(callback)
概述
AJAX 請求完成時執行函數。Ajax 事件。
XMLHttpRequest 對象和設置作為參數傳遞給回調函數
例:
//AJAX 請求完成時執行函數,在HTML追加一個li標簽 $("#msg").ajaxComplete(function(event,request, settings){ $(this).append("<li>請求完成.</li>"); });
//當 AJAX 請求正在進行時顯示“正在載入”的指示 $("#txt").ajaxStart(function(){ $("#wait").css("display","block"); }); $("#txt").ajaxComplete(function(){ $("#wait").css("display","none"); });
ajaxError(callback)
概述
AJAX 請求發生錯誤時執行函數。Ajax 事件。
XMLHttpRequest 對象和設置作為參數傳遞給回調函數。捕捉到的錯誤可作為最後一個參數傳遞。
function (event, XMLHttpRequest, ajaxOptions, thrownError) { // thrownError 只有當異常發生時才會被傳遞 this; // 監聽的 dom 元素 }
例:
//AJAX 請求失敗時顯示信息 $("#msg").ajaxError(function(event,request, settings){ $(this).append("<li>出錯頁面:" + settings.url + "</li>"); });
ajaxStart(callback)
//概述 AJAX 請求開始時執行函數。Ajax 事件。
例:
//AJAX 請求開始時顯示信息 $("#loading").ajaxStart(function(){ $(this).show(); });
ajaxSuccess(callback)
概述
AJAX 請求成功時執行函數。Ajax 事件。
XMLHttpRequest 對象和設置作為參數傳遞給回調函數。
例:
//當 AJAX 請求成功後顯示消息 $("#msg").ajaxSuccess(function(evt, request, settings){ $(this).append("<li>請求成功!</li>"); });
五.跨域AJAX
由於瀏覽器存在同源策略機制,同源策略阻止從一個源載入的文檔或腳本獲取或設置另一個源載入的文檔的屬性。
特別的:由於同源策略是瀏覽器的限制,所以請求的發送和響應是可以進行,只不過瀏覽器不接受罷了。
瀏覽器同源策略並不是對所有的請求均制約:
-
- 制約: XmlHttpRequest
- 不叼: img、iframe、script等具有src屬性的標簽
跨域,跨功能變數名稱訪問,如:http://www.c1.com 功能變數名稱向 http://www.c2.com功能變數名稱發送請求
1、JSONP實現跨域請求
JSONP(JSONP - JSON with Padding是JSON的一種“使用模式”),利用script標簽的src屬性(瀏覽器允許script標簽跨域)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <p> <input type="button" onclick="Jsonp1();" value='提交'/> </p> <p> <input type="button" onclick="Jsonp2();" value='提交'/> </p> <script type="text/javascript" src="jquery-1.12.4.js"></script> <script> function Jsonp1(){ var tag = document.createElement('script'); tag.src = "http://c2.com:8000/test/"; document.head.appendChild(tag); document.head.removeChild(tag); } function Jsonp2(){ $.ajax({ url: "http://c2.com:8000/test/", type: 'GET', dataType: 'JSONP', success: function(data, statusText, xmlHttpRequest){ console.log(data); } }) } </script> </body> </html>基於JSONP實現跨域Ajax - Demo
2、CORS
隨著技術的發展,現在的瀏覽器可以支持主動設置從而允許跨域請求,即:跨域資源共用(CORS,Cross-Origin Resource Sharing),其本質是設置響應頭,使得瀏覽器允許跨域請求。
* 簡單請求 OR 非簡單請求:
條件:
1、請求方式:HEAD、GET、POST
2、請求頭信息:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 對應的值是以下三個中的任意一個
application/x-www-form-urlencoded
multipart/form-data
text/plain
註意:同時滿足以上兩個條件時,則是簡單請求,否則為複雜請求
* 簡單請求和非簡單請求的區別?
簡單請求:一次請求
非簡單請求:兩次請求,在發送數據之前會先發一次請求用於做“預檢”,只有“預檢”通過後才再發送一次請求用於數據傳輸。
* 關於“預檢”:
請求方式:OPTIONS
- “預檢”其實做檢查,檢查如果通過則允許傳輸數據,檢查不通過則不再發送真正想要發送的消息
- 如何“預檢”
=> 如果複雜請求是PUT等請求,則服務端需要設置允許某請求,否則“預檢”不通過
Access-Control-Request-Method
=> 如果複雜請求設置了請求頭,則服務端需要設置允許某請求頭,否則“預檢”不通過
Access-Control-Request-Headers
基於cors實現AJAX請求:
a、支持跨域,簡單請求
伺服器設置響應頭:Access-Control-Allow-Origin = '功能變數名稱' 或 '*'
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <p> <input type="submit" onclick="XmlSendRequest();" /> </p> <p> <input type="submit" onclick="JqSendRequest();" /> </p> <script type="text/javascript" src="jquery-1.12.4.js"></script> <script> function XmlSendRequest(){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4) { var result = xhr.responseText; console.log(result); } }; xhr.open('GET', "http://c2.com:8000/test/", true); xhr.send(); } function JqSendRequest(){ $.ajax({ url: "http://c2.com:8000/test/", type: 'GET', dataType: 'text', success: function(data, statusText, xmlHttpRequest){ console.log(data); } }) } </script> </body> </html>View Code
class MainHandler(tornado.web.RequestHandler): def get(self): self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") self.write('{"status": true, "data": "seven"}')
b、支持跨域,複雜請求
由於複雜請求時,首先會發送“預檢”請求,如果“預檢”成功,則發送真實數據。
- “預檢”請求時,允許請求方式則需伺服器設置響應頭:Access-Control-Request-Method
- “預檢”請求時,允許請求頭則需伺服器設置響應頭:Access-Control-Request-Headers
- “預檢”緩存時間,伺服器設置響應頭:Access-Control-Max-Age