您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Ajax與JavaScript的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
Ajax通信與數據格式無關,從服務器獲取的數據不一定是XML數據。
Ajax的核心:XMLHttpRequest對象(簡稱XHR)
在XHR對象之前,Ajax通信通常使用hack手段,如使用隱藏的或內嵌的框架。
XHR對象為向服務器發送信息和解析服務器響應提供了流暢的接口。
1.XMLHttpRequest對象
IE5是第一款引進XHR對象的瀏覽器,通過MSXML庫中的ActiveX對象實現(有3個版本)。
兼容所有瀏覽器,創建XHR對象:
function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined"){ if (typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i, len; for (i=0,len=versions.length; i < len; i++){ try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (ex){ //skip } } } return new ActiveXObject(arguments.callee.activeXString); } else { throw new Error("No XHR object available."); } }
之后就能在所有瀏覽器創建XHR對象:var xhr = createrXHR();
2.原生XHR對象 (支持的瀏覽器: IE7+、FF、Chrome、Opera、Safari)
通過XMLHttpRequest構建函數,創建XHR對象:
var xhr = new XMLHttpRequest();
3.XHR用法
3-1.open()
open() 3個參數: 發送的類型、請求的URL、表是否異步的布爾值
xhr.open("get","example.php", false);
①URl為相對于執行代碼的當前頁,或絕對地址;
②false為同步,JavaScript代碼會在服務器響應后再繼續執行;
③調用open()只是啟動一個請求以備發送,還沒真正發送;
④只能在同個域中使用相同端口和協議的URL發送請求。
3-2.send()
send() 1個參數: 請求主體發送的數據,不需要通過請求主體發送數據則傳入null。
調用send()后,請求被分派到服務器。
xhr.open("get","example.php", false) ; xhr.send(null);
3-3. 收到響應后,響應數據會自動填充XHR對象的屬性:
responseText:作為響應的主體被返回的文本;
responseXML:若響應的內容類型”text/xml”或”application/xml”,此屬性保存響應數據XML DOM文檔
status:響應的HTTP狀態;
statusText:HTTP狀態的說明。
☆:無論什么內容類型,響應主體的內容都會保存在responseText屬性中。對于非XML數據,responseXML屬性值為null。
3-4.status屬性確認響應是否成功返回
HTTP狀態代碼:
200:響應有效,responseText屬性已就緒,內容類型正確下的responseXML也可訪問。
304:響應有效,只是請求的資源并為修改,可直接使用瀏覽器中緩存的版本。
正確檢查上述2種狀態代碼:
status判斷
if ((xhr.status >= 200 && xhr.status <=300) || xhr.status == 304) { alert(xhr.responseText); } else { alert("Request was unsuccessful:" + xhr.status); };
3-5.readystate屬性
該屬性存儲 請求/響應過程的 當前活動狀態。
0 : 未初始化,未調用open();
1 : 啟動,調用了open();
2 : 發送,調用了send(),未接受響應;
3 : 接受,已接受部分響應;
4 : 完成,已接受全部響應,且可在客戶端使用。
3-6.readystatechange事件
該事件,在readystate屬性值改變時觸發。
readystatechange事件句柄
var xhr = createXHR(); xhr.onreadystatechange = function(event){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("get", "example.txt", true); xhr.send(null);
①必須在調用open()之前知道readystatechange事件的事件處理程序,確保兼容。
②該事件處理程序中沒有傳遞event對象,必須通過XHR對象本地來確定下一步怎么做;
③使用xhr對象而不使用this對象,是因為onreadystatechange事件處理程序的作用域問題。使用this對象在一些瀏覽器會導致函數執行失敗或發生錯誤。
3-7.abort()
調用此方法可取消異步請求:xhr.abort();
調用后,xhr對象停止觸發事件,不允許訪問如何與響應相關的屬性;
終止請求后,應對XHR對象進行解引用操作,不建議重用XHR對象。
4、HTTP頭部信息
發送請求時的頭部信息:
Accept:瀏覽器能夠處理的內容類型
Accept-Charset:瀏覽器能夠顯示的字符集
Accept-Encoding:瀏覽器能夠處理的壓縮編碼
Axxept-Language:瀏覽器當前設置的語言
Connection:瀏覽器與服務器之間連接的類型
Cookie:當前頁面設置的如何Cookie
Host:發送請求耳洞頁面所在域
Referer:發出請求的頁面的URI
User-Agent:瀏覽器的用戶代理字符串
setRequestHeader()
設置自定義頭部信息。
2個參數:頭部字段名稱、頭部信息值。
需在open()方法之后調用send()之前調用setRequestHeader(),才能成功發送請求頭部信息。
自定義HTTP頭部信息
var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("get", "example.php", true); xhr.setRequestHeader("MyHeader", "MyValue"); xhr.send(null);
getRequestHeader()
獲取指定的相應頭部信息
xhr.getRequestHeader(“MyHeader”); getAllRequestHeader()
獲取一個包含所有頭部信息的長字符串
xhr.getAllRequestHeader();
5、GET請求
對于XHR對象,位于opne()的URL末尾的查詢字符串 需經過編碼,使用encodeURIComponent()編碼。
名-值對需用和號(&)分隔。
自定義函數,添加URL查詢字符串參數:
function addURLParam(url,name,value){ url += (url.indexOf('?') == -1?'?':'&'); url += encodeURIComponent(name) + '=' + encodeURIComponent(value); return url; }
6、POST請求
長用于想服務器發送要保存的數據。
由于XHR其初的設計是為了處理XML,故在send(0中可傳入XHR DOM文檔。
6-1.服務端讀取POST數據
①默認情況下,服務器對POST請求和提交Web表單不會一視同仁,故服務端需要程序來讀取發送的原始數據,并解析出有用部分。
②XHR模擬表單提交:
1.將Content-Type頭部信息設置為application/x-www-form-urlencoded (即表單提交時的內容問題);
2.以適當格式創建一個字符串。(通過serialize()函數創建該字符串,序列化表單數據)
XHR模擬表單提交
function submitData(){ var xhr = createXHR(); xhr.onreadystatechange = function(event){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("post", "postexample.php", true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); var form = document.getElementById("user-info"); xhr.send(serialize(form)); }
7、CORS 跨源資源共享(IE8+、FF、Chrome....)
跨域安全策略限制了Ajax的異步通信,CORS則是定義了跨域時,客戶端和服務器的溝通。
CORS思想:使用自定義HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求/響應的成功與否。
7-1.給一個請求附加Origin頭部,包含請求頁面的源信息(協議、域名 和 端口)
Origin: http://www.domain.com
服務器根據Origin判斷是否接收請求,接收則在Access-Control-Allow-Origin頭部會發相同信息。
(若是公共資源,可以回發"*")
Access-Control-Allow-Origin: http://www.domain.com
若無此頭部或頭部信息不匹配,瀏覽器將駁回請求。
☆請求和響應不會包含cookie信息。
7-2.IE8+對CORS的實現
IE8引入的XDR(XDomainRequest)類型,類型XHR,可實現安全可靠的跨域通信。
7-2-1.XDR與XHR的不同之處:
①cookie不會隨請求發送,也不會隨響應返回;
②只能設置請求頭部信息中的Content-Type字段;
③不能訪問響應頭部信息;
④只支持GET和POST請求
XDR緩解了CSRF(跨站請求偽造)和XSS(跨站點腳本)問題
被請求的資源可判斷用戶代理、來源頁面等如何數據 來決定是否設置Access-Control-Allow-Origin頭部
7-2-2. XDR使用方法類似XHR,創建一個XDomainRequest實例,調用open(),再調用send()。
XDR只能執行異步請求,所以open()方法只有兩個參數,請求的類型和URL。
在收到響應后,只能訪問響應的原始文本,無法確定響應的狀態代碼。
只要響應有效就會觸發load事件,響應的數據會保存在responseText屬性中。
如果失敗(如,響應中缺少Access-Control-Allow-Origin頭部)就會觸發error事件,但該事件無有用信息,需要自定義一個onerror事件句柄。
obload事件-onerror事件
var xdr = new XDomainRequest(); xdr.onload = function(){ alert(xdr.responseText); }; xdr.onerror = function(){ alert("Error!"); }; xdr.open("get", "http://www.somewhere-else.com/xdr.php"); xdr.send(null);
在請求返回前調用abort()可終止請求。
7-2-3.XDR也支持timeout屬性及ontiomout事件處理程序,在運行超過timeout設定的秒數后,調用ontimeout事件句柄。
為支持POST請求,XDR提供了contentType屬性,用于表示發送數據的格式。
contentType屬性是XDR對象影響頭部信息的唯一方式。
xdr.contentType = "application/x-www-form-urlencoded";
7-3其他瀏覽器對CORS的實現
FF等瀏覽器都通過XMLHttpRequest對象實現了對CORS的原生支持。要請求另一個域中的資源時,使用標準XHR對象并在open()中傳入絕對URL即可。
標準XHR的跨域
var xhr = createXHR(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("get", "http://www.abc.com/page/", true); xhr.send(null);
與IE不同,通過跨域XHR對象可以訪問status屬性和statusText屬性,也可同步請求。
7-3-1.跨域XHR的限制:
①不能使用setRequestHeader()設置自定義頭部;
②不能發送和接收cookie;
③調用getAllResponseHeader()方法總會返回空字符串。
7-3-2.無論同源請求還是跨域請求都是使用相同的接口,故對于本地資源,最好用相對URL,對遠程資源再用絕對URL。
這樣能消除歧義,避免出現限制訪問頭部或本地cookie信息等問題。
7-4、跨瀏覽器的CORS(IE8+、FF等)
檢測XHR是否支持CORS的方法:檢查是否存在withCredentials屬性,在結合檢測XDomainRequest對象是否存在。
CORS跨域兼容
function createCORSRequest(method, url){ var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr){ xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined"){ xhr = new XDomainRequest(); xhr.open(method, url); } else { xhr = null; } return xhr; } var request = createCORSRequest("get", "http://www.somewhere-else.com/xdr.php"); if (request){ request.onload = function(){ //do something with request.responseText }; request.send(); }
上述createCORSRequest()函數返回的對象的屬性(XHR和XDR的共同屬性):
①abort():停止正在進行的請求;
②onerror:用于替代onreadystatechange檢測錯誤;
③onload:用于代替onreadystatechange檢測成功;
④responseText:用于取得響應內容;
⑤send():用于發送請求。
8、其他跨域技術
在CORS出現前,常利用DOM中能夠執行跨域請求的功能,在不依賴XHR對象時,也能發送某種請求。
與COSR不同的是,不用修改服務器代碼。
8-1.圖像Ping
使用<img>標簽,由于可以從任何網頁加載圖像,故常是在線廣告跟蹤瀏覽量的只要方式。
可動態創建圖像,使用它們的onload和onerror事件句柄,確定是否接受到了響應。
var img = new Image(); img.onload = img.onerror = function(){ alert("Done!"); }; img.src = "http://www.example.com/test?name=Nicholas";
圖像Ping是與服務器進行簡單、單向的跨域通信的一種方式。請求的數據通過查詢字符串形式發送,響應可以是任何內容,通常是像素圖或204響應。雖然通過圖像Ping,瀏覽器得不到任何具體數據,但通過偵聽load和error事件,能找到響應收到的時間。
圖像Ping常用于跟蹤用戶點擊頁面 或動態廣告曝光次數。
缺點:①只能發送GET請求;②無法訪問服務器響應文本。
8-2.JSONP
JSONP(JSON width Padding)填充式JSON或參數式JSON,類似JSON,是包含在函數調用中的JSON:
callback( {"name" : "value"} );
8-2-1.JSONP有兩個部分:回調函數 和 數據
回調函數:當響應到來時應該在頁面中調用的函數。回調函數的名稱在請求中指定。
數據:傳入回調函數的JSON數據。
8-2-2.JSONP通過動態<script>元素,為其src屬性指定一個跨域的URL。類似<img>元素,即都能不受限制地跨域加載資源。
JSONP為有效的JavaScript代碼,在請求完成即JSONP響應 加載到頁面后就會立即執行。
function handleResponse(response){ alert("You're at IP address " + response.ip + ", which is in " + response.city + ", " + response.region_name); } var script = document.createElement("script"); script.src = "http://freegeoip.net/json/?callback=handleResponse"; document.body.insertBefore(script, document.body.firstChild);
headleResponse()為回調函數,將在響應到來后執行。
8-2-3.JSONP之所以流行,是因為 :
①能夠直接訪問響應文本;
②支持瀏覽器與服務器之間的雙向通信。
不足:
①JSONP從其他域加載代碼執行,因此該域必須安全可靠;
②很難確保JSONP請求是否失敗。
8-3Comet ”服務器推送" 【不兼容IE】
Ajax從頁面想服務器請求數據,Comet則是服務器向頁面推送數據,Comet能近乎實時地向頁面推送信息。
8-3-1.實現Comet的2種方式:長輪詢 和 流
①長輪詢:與短輪詢相反,頁面發送一個請求,服務器一直保持連接打開,直到有數據可發送時就向頁面發送數據。接收完數據后瀏覽器關閉連接,隨機又發送一個新請求,在頁面打開期間如此循環...
【短輪詢是服務器立即發送數據,即使數據無效,長輪詢是等待發送響應。】
輪詢的優點是,所有瀏覽器都支持。通過XHR對象和setTimeout()實現。
②HTTP流:它在網頁的整個生命周期內只使用一個HTTP連接。瀏覽器發送一個請求,服務器保持連接打開,再周期性向瀏覽器發送數據.
PHP例子
<?php $i = 0; while (true) { //輸出一些數據,然后刷新輸出緩存 echo "Number is $1"; flush(); //等幾秒 sleep(10); $++; } ...
實現HTTP流的關鍵:所有服務器端語言都支持打印到輸出緩存然后刷新的功能。(將輸出緩存中的內容一次性全部發送給客戶端)
使用XHR實現HTTP流的典型例子
var xhr = new XMLHttpRequest(), received = 0; xhr.open("get", url, true); xhr.onreadystatechange = function(){ var result; if (xhr.readyState == 3){ //get only the new data and adjust counter result = xhr.responseText.substring(received); received += result.length; //call the progress callback progress(result); } else if (xhr.readyState == 4){ finished(xhr.responseText); } }; xhr.send(null); return xhr; } var client = createStreamingClient("streaming.php", function(data){ alert("Received: " + data); }, function(data){ alert("Done!"); });
感謝各位的閱讀!關于“Ajax與JavaScript的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。