傳送門:異步編程系列目錄……示例源碼:
觸碰jQuery:AJAX異步詳解.rarAJAX 全稱 Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。它并非一種新的技術(shù),而是以下幾種原有技術(shù)的結(jié)合體。
1) 使用CSS和XHTML來(lái)表示。
2) 使用DOM模型來(lái)交互和動(dòng)態(tài)顯示。
3) 使用XMLHttpRequest來(lái)和服務(wù)器進(jìn)行異步通信。
4) 使用javascript來(lái)綁定和調(diào)用。
通過(guò)AJAX異步技術(shù),可以在客戶端腳本與web服務(wù)器交互數(shù)據(jù)的過(guò)程中使用XMLHttpRequest對(duì)象來(lái)完成HTTP請(qǐng)求(Request)/應(yīng)答(Response)模型:
1) 不需要用戶等待服務(wù)端響應(yīng)。在異步派發(fā)XMLHttpRequest請(qǐng)求后控制權(quán)馬上就被返回到瀏覽器。界面不會(huì)出現(xiàn)白板,在得到服務(wù)器響應(yīng)之前還可以友好的給出一個(gè)加載提示。
2) 不需要重新加載整個(gè)頁(yè)面。為XMLHttpRequest注冊(cè)一個(gè)回調(diào)函數(shù),待服務(wù)器響應(yīng)到達(dá)時(shí),觸發(fā)回調(diào)函數(shù),并且傳遞所需的少量數(shù)據(jù)?!鞍葱枞?shù)據(jù)”也降低了服務(wù)器的壓力。
3) 不需要使用隱藏或內(nèi)嵌的框架。在XHR對(duì)象之前,模擬Ajax通信通常使用hack手段,如使用隱藏的或內(nèi)嵌的框架(<iframe>標(biāo)簽)。
下面介紹下AJAX中的重要對(duì)象:XMLHttpRequest。
XMLHttpRequest對(duì)象(XHR)
XMLHttpRequest是一套可以在Javascript、VbScript、Jscript等腳本語(yǔ)言中通過(guò)http協(xié)議傳送或接收XML及其他數(shù)據(jù)的一套API。
XMLHttpRequest對(duì)象首次以ActiveX對(duì)象形式在微軟Internet Explorer(IE) 5中以引入。其他瀏覽器制造商在認(rèn)識(shí)到這一對(duì)象重要性后也紛紛實(shí)現(xiàn)了XMLHttpRequest對(duì)象,但是以一個(gè)本地JavaScript對(duì)象而不是作為一個(gè)ActiveX對(duì)象實(shí)現(xiàn)。而如今,由于安全性、標(biāo)準(zhǔn)等問(wèn)題,微軟已經(jīng)在其IE 7中把XMLHttpRequest實(shí)現(xiàn)為一個(gè)本地JavaScript對(duì)象。
API
描述
客服端請(qǐng)求
open(method,url,async, bstrUser, bstrPassword)
規(guī)定請(qǐng)求的類型、URL 以及是否異步處理請(qǐng)求。
1) method:請(qǐng)求的類型,例如:POST、GET、PUT及PROPFIND。大小寫不敏感。
2) url:請(qǐng)求的URL地址,可以為絕對(duì)地址也可以為相對(duì)地址。
3) async[可選]:true(默認(rèn),異步)或 false(同步)。
注釋:當(dāng)您使用async=false 時(shí),JavaScript 會(huì)等到服務(wù)器響應(yīng)就緒才繼續(xù)執(zhí)行。如果服務(wù)器繁忙或緩慢,應(yīng)用程序會(huì)掛起或停止。此時(shí),不需要編寫onreadystatechange回調(diào)函數(shù),把代碼放到 send() 語(yǔ)句后面即可。
4) bstrUser[可選]:如果服務(wù)器需要驗(yàn)證,此處指定用戶名,如果未指定,當(dāng)服務(wù)器需要驗(yàn)證時(shí),會(huì)彈出驗(yàn)證窗口。
5) bstrPassword[可選]:驗(yàn)證信息中的密碼部分,如果用戶名為空,則此值將被忽略。
getRequestHeader(name)
獲取指定的相應(yīng)頭部信息
setRequestHeader(name,value)
自定義HTTP頭部信息。需在open()方法之后和send()之前調(diào)用,才能成功發(fā)送請(qǐng)求頭部信息。
傳送門:
HTTP 頭部詳解Accept
瀏覽器能夠處理的媒體類型
Accept-Charset
瀏覽器申明自己接收的字符集
Accept-Encoding
瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate)
Host
客戶端指定要請(qǐng)求的WEB服務(wù)器的域名/IP 地址和端口號(hào)
Referer
發(fā)出請(qǐng)求的頁(yè)面的URI
Content-Type
標(biāo)明發(fā)送或者接收的實(shí)體的MIME類型。傳送門:
1、
HTTP Content-type對(duì)照表2、
格式:Content-Type: [type]/[subtype]; parameterX-Requested-With
非標(biāo)準(zhǔn)HTTP頭,只為firefox3標(biāo)注是否為ajax異步請(qǐng)求,null表示為同步請(qǐng)求。
默認(rèn)情況下,服務(wù)器對(duì)POST請(qǐng)求和提交Web表單不會(huì)一視同仁,將Content-Type頭部信息設(shè)置為application/x-www-form-urlencoded (模擬表單提交)
send(string)
將請(qǐng)求發(fā)送到服務(wù)器。參數(shù)string僅用于POST請(qǐng)求;對(duì)于GET請(qǐng)求的參數(shù)寫在url后面,所以string參數(shù)傳遞null。
abort()
調(diào)用此方法可取消異步請(qǐng)求,調(diào)用后,XHR對(duì)象停止觸發(fā)事件,不允許訪問(wèn)任何與響應(yīng)相關(guān)的屬性;
服務(wù)端響應(yīng)
onreadystatechange事件
對(duì)于異步請(qǐng)求,如果需要對(duì)服務(wù)器獲取和操作響應(yīng)結(jié)果,則在send() 之前,需要為onreadystatechange屬性指定處理方法。該函數(shù)用于對(duì)服務(wù)器響應(yīng)進(jìn)行處理。
readyState
存有XMLHttpRequest的狀態(tài)。每當(dāng)readyState改變時(shí),就會(huì)觸發(fā)onreadystatechange事件。
從 0 到 4 發(fā)生變化:
0(未初始化)
對(duì)象已建立,但是尚未初始化(尚未調(diào)用open方法)
1(初始化)
對(duì)象已建立,尚未調(diào)用send方法
2(發(fā)送數(shù)據(jù))
send方法已調(diào)用,但是當(dāng)前的狀態(tài)及http頭未知
3(數(shù)據(jù)傳送中)
已接收部分?jǐn)?shù)據(jù),因?yàn)轫憫?yīng)及http頭不全,這時(shí)通過(guò)responseBody和responseText獲取部分?jǐn)?shù)據(jù)會(huì)出現(xiàn)錯(cuò)誤
4(完成)
數(shù)據(jù)接收完畢,此時(shí)可以通過(guò)responseXml和responseText獲取完整的回應(yīng)數(shù)據(jù)
status(數(shù)字表示)
返回當(dāng)前請(qǐng)求的http狀態(tài)碼。
傳送門:
HTTP狀態(tài)碼一覽表(HTTP Status Code)1xx(臨時(shí)響應(yīng))
表示臨時(shí)響應(yīng)并需要請(qǐng)求者繼續(xù)執(zhí)行操作的狀態(tài)代碼。
2xx (成功)
表示成功處理了請(qǐng)求的狀態(tài)代碼。Eg:200
3xx (重定向)
表示要完成請(qǐng)求,需要進(jìn)一步操作。通常,這些狀態(tài)代碼用來(lái)重定向。Eg:304
4xx(請(qǐng)求錯(cuò)誤)
這些狀態(tài)代碼表示請(qǐng)求可能出錯(cuò),導(dǎo)致服務(wù)器無(wú)法正常處理。Eg:404
5xx(服務(wù)器錯(cuò)誤)
這些狀態(tài)代碼表示服務(wù)器在嘗試處理請(qǐng)求時(shí)發(fā)生內(nèi)部錯(cuò)誤。這些錯(cuò)誤可能是服務(wù)器本身的錯(cuò)誤,而不是請(qǐng)求出錯(cuò)。Eg:500
statusText(字符表示)
返回當(dāng)前請(qǐng)求的狀態(tài)文本eg:OK (status:200)
responseText
將響應(yīng)信息作為字符串返回
responseXML
將響應(yīng)信息格式化為Xml Document對(duì)象并返回
responseBody(只有微軟的IE支持)
將響應(yīng)信息正文以u(píng)nsigned byte數(shù)組形式返回(二進(jìn)制數(shù)據(jù))
responseStream(只有IE的某些版本支持)
以Ado Stream對(duì)象(二進(jìn)制流)的形式返回響應(yīng)信息
getResponseHeader(name)
從響應(yīng)信息中獲取指定的http頭
getAllResponseHeaders()
獲取響應(yīng)的所有http頭
overrideMimeType
通常用于重寫服務(wù)器響應(yīng)的MIME類型。Eg,正常情況下XMLHttpRequest只接收文本數(shù)據(jù),但我們可以重寫MIME為“text/plain; charset=x-user-defined”,以欺騙瀏覽器避免瀏覽器格式化服務(wù)器返回的數(shù)據(jù),以實(shí)現(xiàn)接收二進(jìn)制數(shù)據(jù)。
一個(gè)簡(jiǎn)單的ajax封裝:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var myAjax = {
// XMLHttpRequest IE7+, Firefox, Chrome, Opera, Safari ; ActiveXObject IE6, IE5
xhr: window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'),
get: function (url, callback) {
this.xhr.open('get', url);
this.onreadystatechange(callback, this.xhr);
this.xhr.send(null);
},
post: function (url, data, callback) {
this.xhr.open('post', url);
this.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
this.onreadystatechange(callback, this.xhr);
this.xhr.send(data);
},
onreadystatechange: function (func, _xhr) {
_xhr.onreadystatechange = function () {
if (_xhr.readyState == 4) {
if (_xhr.status == 200) {
func(_xhr.responseText);
}
}
}
}
}
使用:
1
2
3
4
5
6
7
8
9
$('#btn_nowTime1').bind('click', null
, function () {
myAjax.post('AjaxHandler.ashx', 'func=GetServerTime'
, function (data) {
if (data)
alert(data);
}
);
});
XMLHttpRequest Level 2
XMLHttpRequest是一個(gè)瀏覽器接口,使得Javascript可以進(jìn)行 HTTP (S) 通信。但是,這個(gè)接口一直沒(méi)有標(biāo)準(zhǔn)化,每家瀏覽器的實(shí)現(xiàn)或多或少有點(diǎn)不同。HTML 5 的概念形成后,W3C 開(kāi)始考慮標(biāo)準(zhǔn)化這個(gè)接口。2008年 2 月,提出了XMLHttpRequest Level 2 草案。
1. 老版本的缺點(diǎn)
老版本的XMLHttpRequest對(duì)象有以下幾個(gè)缺點(diǎn):
1) 只支持文本數(shù)據(jù)的傳送,無(wú)法用來(lái)讀取和上傳二進(jìn)制文件。
2) 傳送和接收數(shù)據(jù)時(shí),沒(méi)有進(jìn)度信息,只能提示有沒(méi)有完成。
3) 受到"同域限制"(Same Origin Policy),只能向同一域名的服務(wù)器請(qǐng)求數(shù)據(jù)。
2. 新版本的功能
新版本的XMLHttpRequest對(duì)象,針對(duì)老版本的缺點(diǎn),做出了大幅改進(jìn)。
1) 可以設(shè)置 HTTP 請(qǐng)求的時(shí)限。
2) 可以使用FormData對(duì)象管理表單數(shù)據(jù)。
3) 可以上傳文件。
4) 可以請(qǐng)求不同域名下的數(shù)據(jù)(跨域資源共享,Cross-origin resource sharing,簡(jiǎn)稱 CORS)。
5) 可以獲取服務(wù)器端的二進(jìn)制數(shù)據(jù)。
6) 可以獲得數(shù)據(jù)傳輸?shù)倪M(jìn)度信息。
3. 介紹幾個(gè)XMLHttpRequest Leve2 新增的成員
超時(shí)時(shí)限
timeout
設(shè)置ajax請(qǐng)求超時(shí)時(shí)限,過(guò)了這個(gè)時(shí)限,就自動(dòng)停止 HTTP 請(qǐng)求。
ontimeout事件
當(dāng)ajax超過(guò)timeout 時(shí)限時(shí)觸發(fā)的回調(diào)函數(shù)。
指定響應(yīng)格式
responseType
(默認(rèn):“text”)在發(fā)送請(qǐng)求前,根據(jù)您的數(shù)據(jù)需要,將xhr.responseType設(shè)置為“text”、“arraybuffer”、“blob”或“document”。
response
成功發(fā)送請(qǐng)求后,xhr的響應(yīng)屬性會(huì)包含DOMString、ArrayBuffer、Blob 或 Document 形式(具體取決于responseTyp的設(shè)置)的請(qǐng)求數(shù)據(jù)。
進(jìn)度信息
progress 事件
在XMLHttpRequest對(duì)象傳遞數(shù)據(jù)的時(shí)候用來(lái)返回進(jìn)度信息。它分成上傳和下載兩種情況。下載的 progress 事件屬于XMLHttpRequest對(duì)象,上傳的 progress 事件屬于XMLHttpRequest.upload對(duì)象。即:
xhr.onprogress = updateProgress;
xhr.upload.onprogress = updateProgress;
XHR還新增了與progress事件相關(guān)的五個(gè)事件:
1) load 事件:傳輸成功完成。
2) abort 事件:傳輸被用戶取消。
3) error 事件:傳輸中出現(xiàn)錯(cuò)誤。
4) loadstart事件:傳輸開(kāi)始。
5) loadEnd事件:傳輸結(jié)束,但是不知道成功還是失敗。
4. 一個(gè)新功能實(shí)例
1) 接收二進(jìn)制數(shù)據(jù)(方法A:改寫MIMEType)
老版本的XMLHttpRequest對(duì)象,只能從服務(wù)器取回文本數(shù)據(jù)。但我們可以改寫數(shù)據(jù)的MIMEType,將服務(wù)器返回的二進(jìn)制數(shù)據(jù)偽裝成文本數(shù)據(jù),并且告訴瀏覽器這是用戶自定義的字符集。
關(guān)鍵代碼如下:
服務(wù)端
1
2
3
4
5
6
7
8
9
10
11
String str = "二進(jìn)制數(shù)據(jù)獲取";
MemoryStream _memory = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(_memory, str);
_memory.Position = 0;
byte[] read = new byte[_memory.Length];
_memory.Read(read, 0, read.Length);
_memory.Close();
context.Response.ContentType = "text/plain";
// 服務(wù)器使用OutputStream輸出二進(jìn)制流
context.Response.OutputStream.Write(read, 0, read.Length);
客服端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$('#btn_mime').bind('click', null
, function () {
$.ajax('AjaxHandler.ashx?func=GetBinaryData',
{
type: 'get',
dataType: 'text',
cache: false,
mimeType: 'text/plain; charset=x-user-defined',
success: function (data) {
if (data) {
var byte = [];
for (var i = 0, len = data.length; i < len; ++i) {
var c = data.charCodeAt(i);
byte[byte.length] = c & 0xff;
}
alert(byte);
}
}
});
});
瀏覽器會(huì)把相應(yīng)數(shù)據(jù)當(dāng)做文本數(shù)據(jù)接收,所以我們還必須再一個(gè)個(gè)字節(jié)地還原成二進(jìn)制數(shù)據(jù)。位運(yùn)算"c & 0xff",表示在每個(gè)字符的兩個(gè)字節(jié)之中,只保留后一個(gè)字節(jié),將前一個(gè)字節(jié)扔掉。原因是瀏覽器解讀字符的時(shí)候,會(huì)把字符自動(dòng)解讀成Unicode 的 0xF700-0xF7ff 區(qū)段。
截圖如下:(測(cè)試環(huán)境:google Chrome 版本 26.0.1410.43)
服務(wù)器端返回二進(jìn)制數(shù)據(jù):
客服端輸出:
a) 使用mimeType: 'text/plain; charset=x-user-defined'參數(shù)。
b) 沒(méi)有對(duì)服務(wù)器的MIME類型進(jìn)行重寫,導(dǎo)致返回信息被瀏覽器格式化后輸出的二進(jìn)制數(shù)據(jù)與服務(wù)器不同。并且不同瀏覽器格式化后輸出的二進(jìn)制數(shù)據(jù)都有差異。
2) 接收二進(jìn)制數(shù)據(jù)(方法B:responseType屬性)
在XMLHttpRequest Level2中,可以使用新增的responseType屬性從服務(wù)器取回二進(jìn)制數(shù)據(jù)。把responseType設(shè)為 blob,表示服務(wù)器傳回的是二進(jìn)制對(duì)象。
1
2
3
var xhr = new XMLHttpRequest();
xhr.open ('GET', '/path/to/image.png');
xhr.responseType = 'blob';
接收數(shù)據(jù)的時(shí)候,用瀏覽器自帶的 Blob 對(duì)象即可。注意,讀取的xhr.response,而不是xhr.responseText。
1
var blob = new Blob ([xhr.response], {type: 'image/png'});
還可以將responseType設(shè)為arraybuffer,把二進(jìn)制數(shù)據(jù)裝在一個(gè)數(shù)組里。然后再遍歷這個(gè)數(shù)組。
1
2
3
4
5
6
7
8
9
10
var xhr = new XMLHttpRequest ();
xhr.open ('GET', '/path/to/image.png');
xhr.responseType = "arraybuffer";
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var byteArray = new Uint8Array (arrayBuffer);
for (vari = 0; i<byteArray.byteLength; i++) {
// do something
}
}
5. 更多XMLHttpRequest Level 2新功能描述請(qǐng)看:
1)
XMLHttpRequest 增強(qiáng)功能2)
XMLHttpRequest Level 2 使用指南3)
XMLHttpRequest2 新技巧jQuery框架的Ajax
jQuery是一個(gè)快速、簡(jiǎn)單的JavaScript library,核心理念是write less,do more(寫的更少,做的更多)。它簡(jiǎn)化了HTML 文件的traversing,事件處理、動(dòng)畫、Ajax 互動(dòng),從而方便了網(wǎng)頁(yè)制作的快速發(fā)展。jQuery是為改變你編寫JavaScript 的方式而設(shè)計(jì)的。更多jQuery科普知識(shí)請(qǐng)看:
jQuery百度百科(Eg:模塊,歷史版本)下面介紹下jQuery框架中ajax相關(guān)API:
版本Jquery-1.7.1.js。
1. jQuery.ajax( [url,] options )
通過(guò) HTTP 請(qǐng)求加載遠(yuǎn)程數(shù)據(jù)。
返回值:$.ajax() 返回jqXHR對(duì)象(jqXHR對(duì)象:為XMLHttpRequest對(duì)象的超集)??捎糜谑謩?dòng)終止請(qǐng)求abort()、為ajax函數(shù)設(shè)置額外的回調(diào)函數(shù)等。
ajax內(nèi)部實(shí)現(xiàn)的兩個(gè)重要對(duì)象:s對(duì)象和jqXHR對(duì)象。
1) s對(duì)象
由默認(rèn)設(shè)置jQuery.ajaxSettings對(duì)象、options參數(shù)集合和jQuery.ajaxSetup({})默認(rèn)設(shè)置合并而成s對(duì)象。
參數(shù)名
描述
可由ajax的options參數(shù)設(shè)置
url
(默認(rèn): 當(dāng)前頁(yè)地址) 要請(qǐng)求的目的URL地址。
username
password
用于響應(yīng)HTTP訪問(wèn)認(rèn)證請(qǐng)求的用戶名及密碼
type
(默認(rèn): "GET") 請(qǐng)求方式 ("POST" 或 "GET")。注意:其它 HTTP 請(qǐng)求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。
dataType
預(yù)期服務(wù)器返回的數(shù)據(jù)類型。如果不指定,jQuery將自動(dòng)根據(jù) HTTP 包 MIME 信息來(lái)智能判斷,比如 XML MIME 類型就被識(shí)別為 XML。隨后服務(wù)器端返回的數(shù)據(jù)會(huì)根據(jù)這個(gè)值解析后,傳遞給回調(diào)函數(shù)。
必須確保網(wǎng)頁(yè)服務(wù)器報(bào)告的 MIME 類型與我們選擇的dataType所匹配。比如說(shuō),XML的話,服務(wù)器端就必須聲明 text/xml 或者 application/xml 來(lái)獲得一致的結(jié)果。
可用值:
"xml"
返回 XML 文檔,可用jQuery處理。
"html"
返回純文本 HTML 信息;包含的 script 標(biāo)簽會(huì)在插入dom時(shí)執(zhí)行。
"script"
返回純文本 JavaScript 代碼,常常用于跨域請(qǐng)求。不會(huì)觸發(fā)全局事件和局部事件;只支持GET方式(POST請(qǐng)求會(huì)自動(dòng)轉(zhuǎn)化為GET請(qǐng)求);默認(rèn)不啟用緩存(cache:false)
"json"
返回 JSON 數(shù)據(jù)。JSON 數(shù)據(jù)是一種能很方便通過(guò) JavaScript 解析的結(jié)構(gòu)化數(shù)據(jù)。
"jsonp"
JSONP 格式,用于跨域請(qǐng)求。
"text"
返回純文本字符串
其中,text 和 xml 類型返回的數(shù)據(jù)不會(huì)經(jīng)過(guò)處理。數(shù)據(jù)僅僅簡(jiǎn)單的將XMLHttpRequest的responseText或responseHTML屬性傳遞給 success 回調(diào)函數(shù)。
如果指定了 script 或者jsonp類型,那么當(dāng)從服務(wù)器接收到數(shù)據(jù)時(shí),實(shí)際上是用了<script>標(biāo)簽而不是XMLHttpRequest對(duì)象。這種情況下,$.ajax() 不再返回一個(gè)XMLHttpRequest對(duì)象,并且也不會(huì)傳遞事件處理函數(shù),比如beforeSend。
contentType
(默認(rèn): "application/x-www-form-urlencoded")標(biāo)明發(fā)送或者接收的實(shí)體的MIME類型。當(dāng)“非GET或HEAD請(qǐng)求”的HTTP請(qǐng)求時(shí),會(huì)被設(shè)置為HTTP頭請(qǐng)求信息。
mimeType
多用途互聯(lián)網(wǎng)郵件擴(kuò)展(MIME,Multipurpose Internet Mail Extensions);用于重寫服務(wù)器端響應(yīng)的MIME類型。
data
發(fā)送到服務(wù)器的數(shù)據(jù)??梢允且粋€(gè)查詢字符串,比如 key1=value1&key2=value2 ,也可以是一個(gè)映射,比如 {key1: 'value1', key2: 'value2'} 。如果使用了后者的形式,則數(shù)據(jù)在發(fā)送前會(huì)通過(guò)jQuery.param()函數(shù)轉(zhuǎn)換成查詢字符串。這個(gè)處理過(guò)程也可以通過(guò)設(shè)置processData選項(xiàng)為false來(lái)回避。
processData
(默認(rèn): true) 默認(rèn)情況下,發(fā)送到服務(wù)器的數(shù)據(jù)(即data參數(shù))將被轉(zhuǎn)換為字符串以配合默認(rèn)內(nèi)容類型 "application/x-www-form-urlencoded"。如果要發(fā)送 DOM 樹(shù)信息或其它不希望轉(zhuǎn)換的信息,請(qǐng)?jiān)O(shè)置為 false。
jQuery中的處理方式:
1
2
3
if ( s.data&&s.processData&&typeofs.data !== "string" ) {
s.data = jQuery.param(s.data, s.traditional );
}
async
(默認(rèn): true) 默認(rèn)設(shè)置下,所有請(qǐng)求均為異步請(qǐng)求。如果需要發(fā)送同步請(qǐng)求,請(qǐng)將此選項(xiàng)設(shè)置為 false。注意,同步請(qǐng)求將鎖住瀏覽器,用戶其它操作必須等待請(qǐng)求完成才可以執(zhí)行。
timeout
設(shè)置請(qǐng)求超時(shí)時(shí)間(毫秒)。通過(guò)setTimeout(fn,time)實(shí)現(xiàn)。
cache
(默認(rèn): true)dataType為 script 和jsonp時(shí)默認(rèn)為 false。設(shè)置為 false 將不緩存此頁(yè)面。
當(dāng)使用GET或HEAD方式發(fā)送請(qǐng)求時(shí)要添加時(shí)間戳參數(shù) (net Date()).getTime() 來(lái)保證每次發(fā)送的URL不同, 可以避免瀏覽器緩存.(只有GET和HEAD方式的請(qǐng)求瀏覽器才會(huì)緩存)
jQuery中的處理方式:
1
2
3
4
5
6
7
if ( s.cache === false ) {
var ts = jQuery.now(),
// rts = /([?&])_=[^&]*/嘗試替換
ret = s.url.replace( rts, "$1_=" + ts );
// rquery = /\?/如果沒(méi)有替換任何內(nèi)容,則把時(shí)間戳加到url最后
s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
}
示例:/AjaxHandler.ashx?func=GetBinaryData&_=1368424995535
ifModified
(默認(rèn): false) 僅在服務(wù)器數(shù)據(jù)改變時(shí)獲取新數(shù)據(jù)。通過(guò)響應(yīng)頭If-Modified-Since、IF-None-Match和請(qǐng)求頭Last-Modified、Etag提高GET或HEAD方式請(qǐng)求效率。(只有GET和HEAD方式的請(qǐng)求瀏覽器才會(huì)緩存)
global
(默認(rèn): true) 是否觸發(fā)全局 AJAX 事件。設(shè)置為 false 將不會(huì)觸發(fā)全局AJAX 事件:ajaxStart、ajaxSend、ajaxSuccess、ajaxError、ajaxComplete、ajaxStop。(比如請(qǐng)求頻繁時(shí)可禁用全局AJAX事件提高效率)
context
(默認(rèn):true) 這個(gè)對(duì)象用于設(shè)置Ajax相關(guān)回調(diào)函數(shù)的上下文,讓回調(diào)函數(shù)內(nèi)this指向這個(gè)對(duì)象。如果不設(shè)定這個(gè)參數(shù),那么回調(diào)函數(shù)中的this就指向調(diào)用本次AJAX請(qǐng)求時(shí)傳遞的options參數(shù)載體“s對(duì)象”。但對(duì)于全局Ajax事件來(lái)說(shuō),this都是指向全局事件所綁定的元素。
jsonp
指定獲得jsonp回調(diào)函數(shù)名的參數(shù)名(默認(rèn)為:callback)。這個(gè)值用來(lái)替代URL中"callback=?"里的"callback"部分,比如{jsonp:'onJsonPLoad'}會(huì)替換為將"onJsonPLoad=?"傳給服務(wù)器。
jsonpCallback
為jsonp請(qǐng)求指定一個(gè)回調(diào)函數(shù)名。jsonpCallback參數(shù)一般為字符串,也可接收函數(shù)(該函數(shù)返回字符串)。
默認(rèn)情況下生成隨機(jī)函數(shù)名:"jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ) + jQuery.now()
crossDomain
(默認(rèn):null)false:同域請(qǐng)求;true跨域請(qǐng)求。
倘若crossDomain標(biāo)識(shí)為null,則jQuery會(huì)自動(dòng)根據(jù)本地url、端口來(lái)解析??梢愿鶕?jù)需求直接賦值來(lái)提高性能。
通常情況下由服務(wù)器自動(dòng)解析即可,但如果你想在同一域中強(qiáng)制跨域請(qǐng)求(像JSONP一樣),那么將crossDomain為true,這允許你將服務(wù)器端重定向到另一個(gè)域。
scriptCharset
只有當(dāng)請(qǐng)求時(shí)dataType為"jsonp"或"script",并且type是"GET"才會(huì)用于修改charset。
因?yàn)榇藭r(shí)是動(dòng)態(tài)創(chuàng)建<script>來(lái)完成腳本加載,但是如果js中的編碼與頁(yè)面的編碼不一致時(shí),js可能加載失敗或者顯示亂碼或者IE下報(bào)某符號(hào)錯(cuò)誤。設(shè)置此參數(shù)就相當(dāng)于為<script>標(biāo)簽設(shè)置charset屬性。
hearders
(默認(rèn):{}) 設(shè)置HTTP請(qǐng)求頭數(shù)據(jù)"{鍵:值}"。此設(shè)置發(fā)生在:jQuery所有影響HTTP頭的參數(shù)(options)設(shè)置之后,beforeSend回調(diào)函數(shù)之前。
statusCode
(默認(rèn):{}) 定義一組HTTP狀態(tài)碼與回調(diào)函數(shù)的映射,當(dāng)響應(yīng)的狀態(tài)碼有匹配statusCode則會(huì)觸發(fā)對(duì)應(yīng)回調(diào)函數(shù)。例如,如果響應(yīng)狀態(tài)是404,將觸發(fā)以下警報(bào):
1
2
3
4
5
$.ajax({
statusCode: {404: function() {
alert('page not found');
}
});
traditional
如果你想要用傳統(tǒng)的方式來(lái)序列化數(shù)據(jù),那么就設(shè)置為true。請(qǐng)參考
$.param()深度遞歸詳解。
xhrFields
聲明附加到XMLHttpRequest對(duì)象的自定義“key-value”數(shù)組。例如,如果需要的話,你可以用它來(lái)設(shè)置
跨域的withCredentials為true,即:
xhrFields: { withCredentials: true }
5個(gè)局部事件
beforeSend、dataFilter、success、error、complete。(詳見(jiàn)后面事件介紹部分)
由ajax函數(shù)內(nèi)部解析或內(nèi)部提供
dataTypes
由dataType按空格拆分所得。
isLocal
根據(jù)協(xié)議確定當(dāng)前url請(qǐng)求的是否為本地請(qǐng)求。
jQuery中定義默認(rèn)值為:
1
isLocal:/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/.test(/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/.exec(url))
hasContent
非GET或HEAD請(qǐng)求為true,用于處理data和contentType參數(shù)。
contents
一個(gè)"{類型字符串:正則表達(dá)式}"的對(duì)象,倘若dataTypes[0]為“*”時(shí),用contents中的正則表達(dá)式去匹配contentType,匹配成功則用“類型字符串”覆蓋dataTypes[0]。
jQuery內(nèi)部定義如下:
1
2
3
4
5
6
contents: {
xml: /xml/,
html: /html/,
json: /json/,
script: /javascript|ecmascript/
}
accepts
瀏覽器能夠處理的媒體類型,其值取決于dataTypes[0]參數(shù)。
jQuery內(nèi)部定義如下:
1
2
3
4
5
6
7
8
accepts: {
xml: "application/xml, text/xml",
html: "text/html",
text: "text/plain",
json: "application/json, text/javascript",
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript",
"*": allTypes // dataTypes[0]匹配不上時(shí)取此值
}
responseFields
jqXHR超集設(shè)置“數(shù)據(jù)類型:屬性”對(duì)應(yīng)關(guān)系,在返回響應(yīng)數(shù)據(jù)時(shí),用于確定創(chuàng)建哪個(gè)屬性變量。
jQuery中定義如下:
1
2
3
4
responseFields: {
xml: "responseXML",
text: "responseText"
}
converters
存儲(chǔ)數(shù)據(jù)類型對(duì)應(yīng)的轉(zhuǎn)換器,根據(jù)dataTypes獲取對(duì)應(yīng)轉(zhuǎn)換器,用于對(duì)響應(yīng)數(shù)據(jù)response進(jìn)行處理。該處理發(fā)生在dataFilter回調(diào)函數(shù)之后。
1
2
3
4
5
6
7
8
9
10
converters: {
"* text": window.String,
"text html": true,
"text json": jQuery.parseJSON,
"text xml": jQuery.parseXML,
"text script": function( text ) {
jQuery.globalEval( text ); // 執(zhí)行腳本
return text;
}
}
2) jqXHR對(duì)象
為不同瀏覽器內(nèi)置的XMLHttpRequest提供了一致的超集。對(duì)于XMLHttpRequest之外的傳輸機(jī)制,比如JSONP請(qǐng)求,jXHR對(duì)象也可以進(jìn)行處理。
超集與真子集:
如果一個(gè)集合S2中的每一個(gè)元素都在集合S1中,且集合S1中可能包含S2中沒(méi)有的元素,則集合S1就是S2的一個(gè)超集。 S1是S2的超集,則S2是S1的真子集,反之亦然。
jqXHR對(duì)象我們常常使用如下成員,這些成員主要用于ajax的全局事件和局部事件,并且做為$.ajax()函數(shù)返回值返回。
1
2
3
4
5
6
7
8
9
10
jqXHR:{
readyState
,setRequestHeader: function( name, value )
,getAllResponseHeaders: function()
,getResponseHeader: function( key )
,overrideMimeType: function( type )
,abort: function( statusText )
,responseText
,responseXML
}
另外,jqXHR的全部成員如下:
在圖中我們看到一些陌生的函數(shù),比如:done()、fail()、promise()、isResolve()、isRejected()、then()、always()、progress()等,都是jQuery的deferred對(duì)象API。
開(kāi)發(fā)網(wǎng)站的過(guò)程中,我們經(jīng)常遇到某些耗時(shí)很長(zhǎng)的javascript操作。其中,既有異步的操作(比如ajax讀取服務(wù)器數(shù)據(jù)),也有同步的操作(比如遍歷一個(gè)大型數(shù)組),它們都不是立即能得到結(jié)果的。
通常的做法是,為它們指定回調(diào)函數(shù)(callback)。即事先規(guī)定,一旦它們運(yùn)行結(jié)束,應(yīng)該調(diào)用哪些函數(shù)。但是,在回調(diào)函數(shù)方面,jQuery的功能非常弱。為了改變這一點(diǎn),jQuery開(kāi)發(fā)團(tuán)隊(duì)就設(shè)計(jì)了deferred對(duì)象。
簡(jiǎn)單說(shuō),deferred對(duì)象就是jQuery的回調(diào)函數(shù)解決方案。在英語(yǔ)中,defer的意思是"延遲",所以deferred對(duì)象的含義就是"延遲"到未來(lái)某個(gè)點(diǎn)再執(zhí)行。 它解決了如何處理耗時(shí)操作的問(wèn)題,對(duì)那些操作提供了更好的控制,以及統(tǒng)一的編程接口。
更專業(yè)的資源:
jQuery的deferred對(duì)象詳解2. jQuery Ajax事件
jQuery框架中,伴隨Ajax請(qǐng)求會(huì)觸發(fā)若干事件,我們可以訂閱這些事件并在其中處理我們的邏輯。在jQuery中有兩種Ajax事件:局部事件和全局事件。
1) 局部事件(回調(diào)函數(shù)),在$.ajax()方法的options參數(shù)中聲明,可以用來(lái)設(shè)置請(qǐng)求數(shù)據(jù)和獲取、處理響應(yīng)數(shù)據(jù)。
beforeSend
該函數(shù)可在發(fā)送請(qǐng)求前修改XMLHttpRequest對(duì)象,如添加自定義 HTTP 頭。
簽名:function (jqXHR,s) { }
函數(shù)說(shuō)明:傳入jqXHR、s對(duì)象
dataFilter
在請(qǐng)求成功之后調(diào)用。若狀態(tài)碼為304(未修改)則不觸發(fā)此回調(diào)。
簽名:function (data, dataType) { return newData; }
函數(shù)說(shuō)明:傳入返回的數(shù)據(jù)、"dataType"參數(shù)的值。并且必須返回新的數(shù)據(jù)傳遞給success回調(diào)函數(shù)
success
請(qǐng)求成功時(shí)觸發(fā)。
簽名:function (data,statusText,jqXHR) { }
函數(shù)說(shuō)明:傳入返回的數(shù)據(jù)、描述狀態(tài)的字符串”success”、jqXHR對(duì)象
error
請(qǐng)求失敗時(shí)調(diào)用此函數(shù)。
簽名:function (jqXHR, textStatus, errorThrown) { }
函數(shù)說(shuō)明:傳入jqXHR對(duì)象、描述狀態(tài)的字符串”error”、錯(cuò)誤信息
complete
請(qǐng)求完成后回調(diào)函數(shù) (請(qǐng)求成功或失敗之后均調(diào)用)
簽名:function (jqXHR, textStatus) { }
函數(shù)說(shuō)明:傳入jqXHR對(duì)象、描述狀態(tài)的字符串(可能值:"No Transport"、"timeout"、"notmodified"---304 "、"parsererror"、"success"、"error")
定義方式例如:
1
2
3
4
5
6
7
8
9
10
$.ajax({
// ...
beforeSend: function(){
// Handle the beforeSend event
},
complete: function(){
// Handle the complete event
}
// ...
});
2) 全局事件,每次Ajax請(qǐng)求都會(huì)觸發(fā),它會(huì)向DOM中的所有元素廣播,你只需為DOM中任意元素bind好全局事件即會(huì)觸發(fā)(若綁定多次,則會(huì)依次觸發(fā)為事件注冊(cè)的回調(diào)函數(shù))。
ajaxStart
開(kāi)始新的Ajax請(qǐng)求,并且此時(shí)jQuery對(duì)象上沒(méi)有其他ajax請(qǐng)求正在進(jìn)行。
簽名:function(e)
函數(shù)說(shuō)明:傳入事件對(duì)象
ajaxSend
當(dāng)一個(gè)Ajax請(qǐng)求開(kāi)始時(shí)觸發(fā)
簽名:function(e,jqXHR,s)
函數(shù)說(shuō)明:傳入事件對(duì)象、jqXHR、s對(duì)象
ajaxSuccess
全局的請(qǐng)求成功
簽名:function(e,jqXHR,s,data)
函數(shù)說(shuō)明:傳入事件對(duì)象、jqXHR、s對(duì)象、請(qǐng)求成功返回的相應(yīng)數(shù)據(jù)
ajaxError
全局的發(fā)生錯(cuò)誤時(shí)觸發(fā)
簽名:function(e,jqXHR,s,errorData)
函數(shù)說(shuō)明:傳入事件對(duì)象、jqXHR、s對(duì)象、請(qǐng)求失敗返回的錯(cuò)誤信息
ajaxComplete
全局的請(qǐng)求完成時(shí)觸發(fā)
簽名:function(e,jqXHR,s)
函數(shù)說(shuō)明:傳入事件對(duì)象、jqXHR、s對(duì)象
ajaxStop
當(dāng)jQuery對(duì)象上正在進(jìn)行Ajax請(qǐng)求都結(jié)束時(shí)觸發(fā)。
簽名:function(e)
函數(shù)說(shuō)明:傳入事件對(duì)象
全局事件在jQuery中的聲明方式:
1
2
3
4
5
jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
jQuery.fn[ o ] = function( f ){
return this.on( o, f );
};
});
所以我們可以使用下面兩種方式定義全局事件:
1
2
3
4
// 可以用bind來(lái)綁定,用unbind來(lái)取消綁定。
$("#loading").bind("ajaxSend", function(){ … });
或者:
$("#loading").ajaxStart(function(){ … });
3) ajax方法完整的事件流
4) 示例:$.ajax()觸發(fā)的事件(局部事件和全局事件)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 全局事件
$("#div_event").ajaxStart(function (e) {
doAddEvent4textarea('txt_event', '觸發(fā)ajaxStart回調(diào)函數(shù)');
});
$("#div_event").ajaxSend(function (e) {
doAddEvent4textarea('txt_event', '觸發(fā)ajaxSend回調(diào)函數(shù)');
});
$("#div_event").ajaxSuccess(function (e, jqXHR, s, data) {
doAddEvent4textarea('txt_event', '觸發(fā)ajaxSuccess回調(diào)函數(shù)');
});
$("#div_event").ajaxError(function (e, jqXHR, s, errorData) {
doAddEvent4textarea('txt_event', '觸發(fā)ajaxError回調(diào)函數(shù)');
});
$("#div_event").ajaxComplete(function (e, jqXHR, s) {
doAddEvent4textarea('txt_event', '觸發(fā)ajaxComplete回調(diào)函數(shù)');
});
$("#div_event").ajaxStop(function (e) {
doAddEvent4textarea('txt_event', '觸發(fā)ajaxStop回調(diào)函數(shù)');
});
// 局部事件
function bindLocalEvent(e) {
var textareaid = e.data.textareaid;
var global = e.data.global;
$.ajax('AjaxHandler.ashx?func=btn_nowTime_long',
{
type: 'get',
dataType: 'text',
global: global,
cache: false,
beforeSend: function (jqXHR, s) {
doAddEvent4textarea(textareaid, '觸發(fā)beforeSend回調(diào)函數(shù)');
},
dataFilter: function (data, dataType) {
doAddEvent4textarea(textareaid, '觸發(fā)dataFilter回調(diào)函數(shù)');
},
success: function (data, statusText, jqXHR) {
doAddEvent4textarea(textareaid, '觸發(fā)success回調(diào)函數(shù)');
},
error: function (jqXHR, textStatus, errorThrown) {
doAddEvent4textarea(textareaid, '觸發(fā)error回調(diào)函數(shù)');
},
complete: function (jqXHR, textStatus) {
doAddEvent4textarea(textareaid, '觸發(fā)complete回調(diào)函數(shù)');
}
});
}
function doAddEvent4textarea(textareaid, txt) {
var textarea = $("#" + textareaid);
textarea.val(textarea.val() + '\r\n' + txt);
}
效果圖:
5) $.ajax()方法的全局事件典型用例
你的頁(yè)面存在多個(gè)甚至為數(shù)不少的ajax請(qǐng)求,但是這些ajax請(qǐng)求都有相同的消息機(jī)制。ajax請(qǐng)求開(kāi)始前顯示一個(gè)提示框,提示“正在讀取數(shù)據(jù)”;ajax請(qǐng)求成功時(shí)提示框顯示“數(shù)據(jù)獲取成功”;ajax請(qǐng)求結(jié)束后隱藏提示框。
a) 不使用全局事件的做法是:
給$.ajax()加上beforeSend、success、complete回調(diào)函數(shù),在回調(diào)函數(shù)中加上處理提示框。
b) 使用全局事件的做法是:
1
2
3
4
5
6
$(document).ajaxStart(onStart)
.ajaxComplete(onComplete)
.ajaxSuccess(onSuccess);
function onStart(event) { //..... }
function onComplete(event, xhr, settings) { //..... }
function onSuccess(event, xhr, settings) { //..... }
3. jQuery ajax相關(guān)函數(shù)
1) jQuery.ajaxSetup({ })
jQuery.ajax()函數(shù)中的所有的參數(shù)選項(xiàng)都可以通過(guò)jQuery.ajaxSetup()函數(shù)來(lái)全局設(shè)置默認(rèn)值。
2) $.ajax()函數(shù)的封裝
a) $("").load(url [, params] [, callback])
請(qǐng)求遠(yuǎn)程的HTML文件代碼(dataType: "html"),默認(rèn)使用 GET 方式,如果傳遞了params參數(shù)則使用Post方式。在請(qǐng)求“成功”完成時(shí)將responseText屬性值插入至DOM中。但不管請(qǐng)求是否成功完成“在最后”都會(huì)執(zhí)行callback回調(diào)函數(shù)(即:complete:callback)。
b) jQuery.get(url [, data] [, callback] [, type] )
通過(guò)HTTP GET請(qǐng)求載入數(shù)據(jù),并在請(qǐng)求成功時(shí)執(zhí)行回調(diào)函數(shù)(即:success: callback)。
c) jQuery.getJSON(url [, data] [, callback] )
通過(guò) HTTP GET 請(qǐng)求載入 JSON 數(shù)據(jù)。相當(dāng)于: jQuery.get(url, [data],[callback], "json")
可以通過(guò)使用JSONP 形式的回調(diào)函數(shù)來(lái)加載其他網(wǎng)域的JSON數(shù)據(jù)。
d) jQuery.getScript(url [, callback] )
通過(guò) HTTP GET 請(qǐng)求載入并執(zhí)行一個(gè) JavaScript 文件。相當(dāng)于: jQuery.get(url, null, [callback], "script")
可以跨域調(diào)用 JavaScript 文件。
e) jQuery.post(url [, data] [, callback] [, type] )
通過(guò) HTTP POST 請(qǐng)求載入信息,并在請(qǐng)求成功時(shí)執(zhí)行回調(diào)函數(shù)(即:success: callback)。
3) 對(duì)象序列化
a) jQuery.param(object,traditional)
創(chuàng)建數(shù)組或?qū)ο蟮男蛄谢硎荆撔蛄谢稍赼jax請(qǐng)求時(shí)在URL查詢字符串中使用。
序列化過(guò)程中會(huì)使用encodeURIComponent()函數(shù)把字符串作為URI組件進(jìn)行編碼。
encodeURIComponent() 方法不會(huì)對(duì) ASCII 字母和數(shù)字進(jìn)行編碼,也不會(huì)對(duì)這些 ASCII 標(biāo)點(diǎn)符號(hào)進(jìn)行編碼: - _ . ! ~ * ' ( ) 。其他字符(比如:;/?:@&=+$,# 這些用于分隔 URI 組件的標(biāo)點(diǎn)符號(hào)),都是由一個(gè)或多個(gè)十六進(jìn)制的轉(zhuǎn)義序列替換的。
1
2
3
4
5
6
// 在param中會(huì)進(jìn)行如下處理
function( key, value ) {
// 如果value是函數(shù),則取其函數(shù)返回值
value = jQuery.isFunction( value ) ? value() : value;
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
};
對(duì)于 jQuery 1.4,$.param() 方法將會(huì)通過(guò)深度遞歸的方式序列化對(duì)象,以便符合現(xiàn)代化腳本語(yǔ)言的需求,比如 PHP、Ruby on Rails 等。你可以傳遞traditional = true 或在ajax功能中傳遞包含traditional的options參數(shù)。
傳送門:
$.param()深度遞歸詳解和
$.param() 示例b) $("").serializeArray()
可以將一個(gè)或多個(gè)表單元素(比如 input、 textarea等),或者 form 元素本身的jQuery對(duì)象序列化為JSON對(duì)象。(非 JSON 字符串。需要使用插件或者第三方庫(kù)進(jìn)行字符串化操作)
特別說(shuō)明,元素不能被禁用(禁用的元素不會(huì)被包括在內(nèi)),并且元素應(yīng)當(dāng)有含有 name 屬性。提交按鈕的值也不會(huì)被序列化。文件選擇元素的數(shù)據(jù)也不會(huì)被序列化。
傳送門:
c) $("").serialize()可以將一個(gè)或多個(gè)表單元素(比如 input、 textarea等),或者 form 元素本身的jQuery對(duì)象序列化為經(jīng)過(guò)URL編碼轉(zhuǎn)換后的字符串,可直接用在URL查詢字符串中。jQuery內(nèi)部定義:123serialize: function() {return jQuery.param( this.serializeArray() );}$.ajax()中常見(jiàn)應(yīng)用示例1. cache和ifModified參數(shù)1) cache參數(shù):GET和POST最重要的區(qū)別(傳送門)語(yǔ)義上,GET是獲取指定URL上的資源,是讀操作,重要的一點(diǎn)是不論對(duì)某個(gè)資源GET多少次,它的狀態(tài)是不會(huì)改變的,在這個(gè)意義上,我們說(shuō)GET是安全的(不是被密碼學(xué)或者數(shù)據(jù)保護(hù)意義上的安全)。因?yàn)镚ET是安全的,所以GET返回的內(nèi)容可以被瀏覽器,Cache服務(wù)器緩存起來(lái)。
而POST的語(yǔ)意是對(duì)指定資源“追加/添加”數(shù)據(jù),所以是不安全的,每次提交的POST,參與的代碼都會(huì)認(rèn)為這個(gè)操作會(huì)修改操作對(duì)象資源的狀態(tài),于是,瀏覽器在你按下F5的時(shí)候會(huì)跳出確認(rèn)框,緩存服務(wù)器不會(huì)緩存POST請(qǐng)求返回內(nèi)容。
2) ifModified參數(shù):通過(guò)ifModified參數(shù)提高請(qǐng)求性能(即:“條件GET”:Last-Modified / If-Modified-Since和ETag / If-None-Match)
當(dāng)你請(qǐng)求的資源并不是一層不變的時(shí)候,即不能簡(jiǎn)單的一直使用客戶端緩存時(shí),你可能通過(guò)將cache設(shè)置為false來(lái)發(fā)送請(qǐng)求,這實(shí)際上是在url加上時(shí)間戳組合成新的url,每次發(fā)送新的請(qǐng)求,這明顯加大了服務(wù)器的壓力。
對(duì)于這種情況,我們可以通過(guò)ifModified參數(shù)改進(jìn)緩存方式(即:cache和ifModified都設(shè)置為true),僅在請(qǐng)求的數(shù)據(jù)改變時(shí)重新獲取。通過(guò)這種方式請(qǐng)求的url不會(huì)改變,并且每次都會(huì)發(fā)送到服務(wù)器,只是會(huì)有檢驗(yàn)方法驗(yàn)證是否需要重新獲取數(shù)據(jù)從而節(jié)省帶寬和開(kāi)銷。
更多ETag描述(優(yōu)點(diǎn),解決了Last-Modified無(wú)法解決的一些問(wèn)題,什么場(chǎng)合不應(yīng)該被使用)過(guò)程如下:
a) 將$.ajax()函數(shù)的cache和ifModified參數(shù)同時(shí)設(shè)置為true。
b) 客戶端請(qǐng)求服務(wù)端A,在服務(wù)端加上Last-Modified/ETag響應(yīng)體一起返回。
c) 客戶端緩存接收到的Last-Modified/ETag響應(yīng)體,并在下一次發(fā)生請(qǐng)求A時(shí)將緩存的Last-Modified/ETag值做為If-Modified-Since/IF-None-Match請(qǐng)求頭一起發(fā)給服務(wù)器。
d) 服務(wù)器接收If-Modified-Since/IF-None-Match后,就根據(jù)參數(shù)值檢驗(yàn)自上次客服端請(qǐng)求之后資源是否有改動(dòng)
i. 若還未改動(dòng)則直接返回響應(yīng)304和一個(gè)空的響應(yīng)體。
ii. 若已改動(dòng)則重新處理數(shù)據(jù),返回最新的請(qǐng)求數(shù)據(jù)。
e) 這樣,既保證不向客戶端重復(fù)發(fā)出資源,也保證當(dāng)服務(wù)器有變化時(shí),客戶端能夠得到最新的資源。
這一過(guò)程中,我們只需要做:服務(wù)器返回Last-Modified/ETag響應(yīng)頭和在服務(wù)端檢驗(yàn)數(shù)據(jù)是否失效并采取對(duì)應(yīng)處理方式。其余步驟由jQuery框架的ajax()函數(shù)完成。
關(guān)鍵代碼如下:
客服端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$('#btn_nowTime_long3').bind('click', null
, function () {
$.ajax('AjaxHandler.ashx?func=GetServerTime4Modified',
{
type: 'get',
dataType: 'text',
cache: true,
ifModified: true,
success: function (data) {
if (data)
alert(data);
},
});
});
服務(wù)端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(!String.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"]))
{
if (CheckResourceValidate()) // 檢查資源有效性
{
// 如果資源有效,則直接返回304狀態(tài)碼,客戶端回去到此狀態(tài)碼后會(huì)從緩存中取值。
context.Response.StatusCode = 304;
return;
}
}
// 請(qǐng)求數(shù)據(jù)
GetServerTimeAfter2Second();
context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
// 設(shè)置Last-Modified響應(yīng)體
context.Response.Cache.SetLastModified(DateTime.Now);
2. 跨域請(qǐng)求
在JavaScript中,有一個(gè)很重要的安全性限制,被稱為“Same-Origin Policy”(同源策略)。這一策略對(duì)于JavaScript代碼能夠訪問(wèn)的頁(yè)面內(nèi)容做了很重要的限制,即JavaScript只能訪問(wèn)與包含它的文檔在同一域下的內(nèi)容。所謂同源是指,域名(host),協(xié)議(protocol),端口(port)相同。
URL
說(shuō)明
是否允許通信
能否通過(guò)javascript解決
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下
允許
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不同文件夾
允許
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不同端口
不允許
能
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同協(xié)議(http和https)
不允許
不能
http://www.a.com/a.js
http://70.32.92.74/b.js
域名和域名對(duì)應(yīng)ip不允許
能
http://www.cnblogs.com/a.js
http://www.a.com/b.js
http://script.a.com/b.js
http://a.com/b.js
不同域名(host)
不允許
能
1) $.ajax()為我們提供了兩種解決方案,不過(guò)都是只支持get方式,分別是jQuery的jQuery.ajax“jsonp”格式和jquery.getScript()(即jQuery.ajax “script”格式)方式。
2) $.ajax()跨域原理分析
由于javascript的安全限制“同源策略”,所以我們無(wú)法使用XMLHttpRequest直接請(qǐng)求別的域名下的資源。不過(guò)擁有src屬性和href屬性的<script>\<img>\<iframe>和<link>\<a>標(biāo)簽不受同源策略影響。$.ajax()提供的兩種解決方案正是應(yīng)用了動(dòng)態(tài)創(chuàng)建<script>的方式來(lái)實(shí)現(xiàn)(即:生成<script>標(biāo)簽,src引入腳本,然后執(zhí)行,最后移除<script>標(biāo)簽)。
3) jQuery.ajax()的jsonp和script方式的異同點(diǎn):
a) 相同:都走$.ajax() script格式的流程;不會(huì)觸發(fā)全局事件和局部事件;只支持GET方式(POST請(qǐng)求會(huì)自動(dòng)轉(zhuǎn)化為GET請(qǐng)求);默認(rèn)不啟用緩存(cache:false)
b) 不同:jsonp方式可以通過(guò)jsonp和jsonpCallback參數(shù)指定一個(gè)特定回調(diào)函數(shù)。
4) 示例部署說(shuō)明:
因?yàn)槭强缬蛘?qǐng)求,所以需要在本機(jī)部署兩個(gè)示例程序以模擬不同域之間的訪問(wèn),并且在示例代碼中需要修改“crossUrl”為目的域路徑。
5) jsonp示例代碼:
客服端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// jsonp方式跨域請(qǐng)求(dataType:jsonp)
$('#btn_cross_req1').bind('click', null
, function () {
$.ajax(crossUrl,
{
type: 'get',
dataType: 'jsonp',
jsonp: 'jsonpParamName',
jsonpCallback: 'crossCallback',
crossDomain: true,
});
});
function crossCallback(data) {
alert('jsonp' + data);
}
服務(wù)端:
1
2
3
4
context.Response.ContentType = "text/plain";
string jsonpCallbackName = reqCollection["jsonpParamName"];
context.Response.Write(String.Format("{0}('來(lái)自域:{1}的相應(yīng)信息')"
, jsonpCallbackName, context.Request.Url.Host));
分析:
a) 因jsonp和jsonpCallback參數(shù)而改變的url如下。(即默認(rèn)為:callback=jQuery隨機(jī)值,更改為:jsonpParamName=crossCallback)
URL:http://192.168.1.100:6567/AjaxHandler.ashx?func=CrossRequest&jsonpParamName=crossCallback&_=1368360234428
b) 服務(wù)器端獲取到j(luò)sonp回調(diào)函數(shù)名后,返回一個(gè)函數(shù)表達(dá)式。
6) 在XMLHttpRequest Level 2中新增了跨域訪問(wèn)方式、接收二進(jìn)制等新功能,詳細(xì)請(qǐng)看:
XMLHttpRequest2 新技巧最后,再來(lái)一張示例截圖吧?。?!
示例源碼:
觸碰jQuery:AJAX異步詳解.rar本篇博文到此結(jié)束,主要介紹內(nèi)容是使用XMLHttpRequest實(shí)現(xiàn)ajax請(qǐng)求和XMLHttpRequest Level 2為我們所帶來(lái)的改進(jìn),最后重點(diǎn)講解了jQuery中通過(guò)$.ajax()方法實(shí)現(xiàn)ajax以及各個(gè)參數(shù)的詳細(xì)介紹,并立舉了經(jīng)典示例說(shuō)明了:跨域請(qǐng)求、ajax全局事件、ajax局部事件、xhr二進(jìn)制數(shù)據(jù)處理、如何高效使用緩存……
做為一個(gè)后臺(tái)工程師,你是否想深入了解一些前臺(tái)必須的技術(shù)呢?是的,我想了解,并且會(huì)慢慢把所了解到的技術(shù)以博文的方式整理分享給大家。
謝謝大家查閱,如果覺(jué)得文章不錯(cuò),還請(qǐng)多多幫推薦……
文中出現(xiàn)比較多的相關(guān)資源鏈接,這里整理下方便大家日后快速找到鏈接:
1) jQuery相關(guān)
jQueryAPI文檔jQuery百度百科(Eg:模塊,歷史版本)Ajax 技術(shù)資源中心(IBM)這是有關(guān) Ajax 編程模型信息的一站式中心,包括很多文檔、教程、論壇、blog、wiki 和新聞。任何 Ajax 的新信息都能在這里找到。
jQuery.ajax()中的預(yù)過(guò)濾器和分發(fā)機(jī)制函數(shù)inspectPrefiltersOrTransports詳解jQuery的deferred對(duì)象詳解$.param()深度遞歸詳解2) XMLHttpRequest Level 2 的新功能相關(guān)
XMLHttpRequest 增強(qiáng)功能XMLHttpRequest Level 2 使用指南XMLHttpRequest2 新技巧3) 跨域請(qǐng)求相關(guān)
JavaScript跨域總結(jié)與解決辦法總結(jié)了5種js跨域方式:利用<iframe>標(biāo)簽和document.domain屬性、動(dòng)態(tài)創(chuàng)建scrip、利用<iframe>標(biāo)簽和location.hash屬性、window.name實(shí)現(xiàn)的跨域數(shù)據(jù)傳輸、使用HTML5 postMessage、
利用flash跨域。
域名和IP地址及域名解析xhr注入_百度百科說(shuō)說(shuō)JSON和JSONP4) HTTP相關(guān)
HTTP深入淺出 http請(qǐng)求1) 介紹了一次HTTP通信的7個(gè)步驟:建立TCP連接、Web瀏覽器向Web服務(wù)器發(fā)送請(qǐng)求命令、Web瀏覽器發(fā)送請(qǐng)求頭信息、Web服務(wù)器應(yīng)答、Web服務(wù)器發(fā)送應(yīng)答頭信息、Web服務(wù)器向?yàn)g覽器發(fā)送數(shù)據(jù)、Web服務(wù)器關(guān)閉TCP連接
2) 介紹HTTP請(qǐng)求格式
HTTP GET和POST的區(qū)別HTTP 頭部詳解HTTP Content-type對(duì)照表格式:Content-Type: [type]/[subtype]; parameterHTTP狀態(tài)碼一覽表(HTTP Status Code)5)Jquery其他部分
不定義JQuery插件,不要說(shuō)會(huì)JQuery================================================
求職:ASP.NET高級(jí)工程師。(地點(diǎn):廣州,深圳)
今晚準(zhǔn)備簡(jiǎn)歷,步上新的求職之旅。希望有好工作推薦的園友給點(diǎn)幫助。
另外,我有關(guān)注 廣州多益、3g門戶網(wǎng)、廣州39健康網(wǎng) 公司,如有內(nèi)部信息或你是內(nèi)部員工,我很希望能與你交流。QQ:369220123
如果你想認(rèn)識(shí).net朋友的可以加入群:185718116(廣深莞·NET技術(shù)) 173844862(.Net高級(jí)部落)
================================================