Ajax是一種技術(shù),一種能夠向服務(wù)器請求額外的數(shù)據(jù)而無需卸載頁面的技術(shù),能夠使網(wǎng)頁具備更優(yōu)的用戶體驗。Ajax技術(shù)的核心是XMLHttpRequest對象(XHR)。本文從XHR開始談起,理解Ajax技術(shù)的特點,再對跨域以及Comet等技術(shù)進行簡要理解和總結(jié)。
成都創(chuàng)新互聯(lián)公司是專業(yè)的武穴網(wǎng)站建設(shè)公司,武穴接單;提供網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行武穴網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
XMLHttpRequest基本用法
XHR對象有兩個常用的方法open和send。open方法用戶啟動一個HTTP請求,不過它不會真的發(fā)送HTTP請求。open方法接收3個參數(shù),分別表示請求的HTTP方法、請求的URL、是否異步。XHR對象的第二個方法send用于發(fā)送open所啟動的請求。send方法接收1個參數(shù),表示HTTP請求的主體數(shù)據(jù)。如果發(fā)送的是GET請求這種沒有附帶主體數(shù)據(jù)的HTTP請求,則傳入null即可。如果是POST請求,則傳入需要POST的數(shù)據(jù)。下面是一個簡單示例,向/api/data發(fā)起一個GET請求,并且是采取異步的方式發(fā)送請求,即該請求不會阻塞頁面中其他js代碼的執(zhí)行。
var xhr = new XMLHttpRequest() xhr.open("get", "/api/data", true) xhr.send(null)
請求得到的響應(yīng)數(shù)據(jù)會自動填充到XHR對象的屬性上,主要有下面4個屬性:
* responseText: 響應(yīng)主體文本
* responseXML: 如果響應(yīng)內(nèi)容類型是"text/xml"或"application/xml", 這個屬性中將包含響應(yīng)數(shù)據(jù)的XML DOM文檔
* status: 響應(yīng)的HTTP狀態(tài)碼,一般可以將HTTP狀態(tài)嗎200視為成功的標(biāo)識
* statusText: HTTP狀態(tài)的說明
XHR對象有1個readyState屬性記錄了該對象從創(chuàng)建到收到響應(yīng)數(shù)據(jù)可能會經(jīng)歷的5種狀態(tài),readyState的可能取值如下:
0: 還沒有調(diào)用open()方法初始化請求
1: 已經(jīng)調(diào)用open()方法但是還沒有調(diào)用send()方法
2: 已經(jīng)調(diào)用send()方法但是還沒有收到響應(yīng)
3: 收到部分響應(yīng)數(shù)據(jù),還有部分?jǐn)?shù)據(jù)沒收到
4: 收到全部響應(yīng)數(shù)據(jù),即響應(yīng)結(jié)束,數(shù)據(jù)完備
當(dāng)readyState從一個值變到另一個值的時候會觸發(fā)readystatechange事件,當(dāng)這個事件觸發(fā)的時候只需要在事件處理器里面檢查一下readyState的值是否為4,當(dāng)其值為4的時候就可以對響應(yīng)的數(shù)據(jù)做后續(xù)處理了。給readystatechange事件指定處理器必須在調(diào)用open()方法之前完成才能確保跨瀏覽器兼容性。下面是簡單示例。
var xhr = new XMLHttpRequest() xhr.onreadystatechange = function() { if (xhr.readyState === 4) { console.log(xhr.status, xhr.responseText) } } xhr.open("get", "/api/data", true) xhr.send(null)
XHR對象提供setRequestHeader()方法可以設(shè)置請求的自定義HTTP頭部信息,該方法接收兩個參數(shù),要設(shè)置的字段和該字段的值。在調(diào)用open()啟動一個請求之后并且在send()發(fā)送請求之前調(diào)用setRequestHeader()才能設(shè)置成功。請求得到響應(yīng)之后,可以通過getResponseHeader()方法獲取響應(yīng)的HTTP頭部信息,該方法接收1個參數(shù),即要獲取的字段名。而通過getAllResponseHeaders()則可以獲得所有頭部信息組成的長字符串。下面是簡單示例。
var xhr = new XMLHttpRequest() xhr.onreadystatechange = function() { if (xhr.readyState === 4) { console.log(xhr.status, xhr.responseText) console.log(xhr.getResponseHeader('SomeKey')) console.log(xhr.getAllResponseHeaders()) } } xhr.open("get", "/api/data", true) xhr.setRequestHeader("SomeKey", "SomeValue") xhr.send(null)
FormData
XMLHttpRequest 2級定義了FormData類型為序列化表單、創(chuàng)建與表單格式相同的數(shù)據(jù)、用于XHR傳輸提供便利。FormData提供append()方法可以直接添加數(shù)據(jù),該方法接收兩個參數(shù)鍵和值。FormData的構(gòu)造函數(shù)可以不傳參數(shù),也可以直接傳入1個表單元素。傳入表單元素之后會利用該表單元素的數(shù)據(jù)來向FormData對象預(yù)先填入鍵值對。下面是簡單示例。
var form = document.getElementById('myForm') var data = new FormData(form) data.append('someKey', 'someValue') var xhr = new XMLHttpRequest() xhr.onreadystatechange = function() { if (xhr.readyState === 4) { console.log(xhr.responseText) } } xhr.open('post', '/api/upload', true) xhr.send(data)
跨域資源共享
通過XHR實現(xiàn)Ajax通信會遇到一個限制,即跨域安全策略。跨域安全策略限制了“相同域名、相同端口、相同協(xié)議”,當(dāng)XHR想要訪問限制之外的資源就會引發(fā)安全錯誤。CORS(Cross-Origin Resource Sharing),跨域資源共享,其思想是通過使用自定義HTTP頭部讓瀏覽器與服務(wù)器進行溝通從而決定請求或者響應(yīng)的成功與失敗,需要瀏覽器和服務(wù)器同時支持才能實現(xiàn)正常的訪問。目前大部分瀏覽器已經(jīng)支持了CORS,所以寫起代碼跟普通的同域資源訪問幾乎一樣,就只是把URL用絕對路徑表示。因此,要實現(xiàn)跨域的關(guān)鍵還是在服務(wù)器,具體如何實現(xiàn)本文不深入討論。下面是前端js的簡單示例。
var xhr = new XMLHttpRequest() xhr.onreadystatechange = function() { if (xhr.readyState === 4) { console.log(xhr.responseText) } } xhr.open('get', 'http://www.otherserver.com/api/data', true) xhr.send(null)
JSONP
JSONP(JSON with padding)是應(yīng)用JSON實現(xiàn)跨域資源訪問的一種方法。JSONP由兩部分內(nèi)容組成:回調(diào)函數(shù)和JSON數(shù)據(jù)。前面說過,XHR請求會遇到跨域安全策略的限制,但是HTML中的script標(biāo)簽則不會有這個限制,我們可以通過script標(biāo)簽引用不同域里面的js文件。JSONP便是鉆了這個空子,它通過動態(tài)創(chuàng)建script元素,然后把src指向其他域的URL從而實現(xiàn)加載其他域的資源,然后通過回調(diào)函數(shù)來處理加載得到的數(shù)據(jù)。下面是一個簡單示例。
function handler(res) { console.log(res) } var script = document.createElement('script') script.src = 'http://www.otherserver.com/api/data/?callback=handler' document.body.insertBefore(script, document.body.firstChild)
上述代碼指定了動態(tài)創(chuàng)建的script元素的src為另一個域名下面的/api/data,然后指明回調(diào)函數(shù)為handler。將script插入到DOM里面之后會向?qū)?yīng)的URL加載數(shù)據(jù),完成之后會將得到的JSON數(shù)據(jù)解析成一個對象并調(diào)用handler進行處理。
JSONP是實現(xiàn)跨域訪問的一種簡單的方法,不過也存在一些安全問題,例如請求的其他域的URL響應(yīng)給你一段惡意代碼。JSONP還有一個問題,script標(biāo)簽引用的是js,json由于被js所支持所以也可以引用,因此在請求其他域的URL時需要確認(rèn)它是否以json格式進行響應(yīng),而不是XML。
Comet
Ajax是一種從網(wǎng)頁向服務(wù)器請求數(shù)據(jù)的技術(shù),而Comet與之相反,它是從服務(wù)器向網(wǎng)頁推送數(shù)據(jù)的技術(shù),適用于實時性要求比較高的應(yīng)用。實現(xiàn)Comet的方式有兩種:長輪詢和流。在說長輪詢之前先說一下短輪詢,它的思路很簡單,就是客戶端使用定時器,每隔一定的時間間隔就向服務(wù)器發(fā)送Ajax請求看看有沒有數(shù)據(jù)更新,這個時間間隔一般很小。長輪詢同樣也是客戶端不斷向服務(wù)器發(fā)送請求,不同的是,客戶端不需要按照時間間隔不斷地發(fā)送請求,而是發(fā)起1個請求到服務(wù)器之后,客戶端和服務(wù)器之間的HTTP連接保持打開,直到服務(wù)器有數(shù)據(jù)更新就通過這個連接向客戶端響應(yīng)數(shù)據(jù),然后再關(guān)閉這個HTTP連接。關(guān)閉之后瀏覽器再發(fā)起一個新的連接繼續(xù)重復(fù)前面的過程。相比短輪詢,長輪詢發(fā)起的HTTP連接次數(shù)更少了,不過如果HTTP連接長時間保持開放也是在占用服務(wù)器的資源。
第二種實現(xiàn)Comet的方式是基于HTTP流,客戶端向服務(wù)器發(fā)起1個HTTP連接,全程保持這個連接打開,客戶端周期性地通過這個連接向服務(wù)器獲取數(shù)據(jù)查看更新。
SSE
SSE(Server-Send Events),服務(wù)器發(fā)送事件,是一種實現(xiàn)Comet交互的瀏覽器API,支持輪詢也支持HTTP流。SSE API用于創(chuàng)建到服務(wù)器的單向連接,服務(wù)器通過這個連接可以發(fā)送任意數(shù)量的數(shù)據(jù)給客戶端。服務(wù)器響應(yīng)的MIME類型為text/event-stream。下面是SSE的JavaScript API的簡單示例。
var source = new EventSource("/api/events") source.onmessage = function(event) { console.log(event.data) }
如上面代碼所示,要向服務(wù)器預(yù)定事件流獲取服務(wù)器發(fā)送的數(shù)據(jù),首先創(chuàng)建EventSource對象,然后在message事件觸發(fā)的時候進行處理。服務(wù)器發(fā)送的數(shù)據(jù)以字符串形式保存在event.data中。EventSource對象會保持與服務(wù)器的活動連接,如果中間斷開會重新連接,如果要真正地斷開連接可以通過調(diào)用close()方法來實現(xiàn)。EventSource的message事件會在從服務(wù)器收到新事件的時候觸發(fā),除了message事件之外它還有另外2個事件open和error,open事件在建立連接的時候觸發(fā),error事件在無法建立連接的時候觸發(fā)。
Web Sockets
Web Sockets是一種與服務(wù)器進行全雙工雙向通信的通道。Web Sockets不適用HTTP協(xié)議,而前面說的Ajax和Comet都是使用HTTP協(xié)議。篇幅關(guān)系本文對Web Sockets不作討論。
總結(jié)
Ajax實現(xiàn)在不加載頁面的情況下向服務(wù)器請求數(shù)據(jù),提升網(wǎng)頁的用戶體驗。實現(xiàn)Ajax技術(shù)的XHR會遇到跨域安全策略的限制,通過CORS解決跨域問題需要瀏覽器和服務(wù)器兩端的配合。JSONP是一種實現(xiàn)跨域訪問的”小技巧“但也是存在一些問題。Comet對Ajax進行了拓展,讓服務(wù)器能夠?qū)崟r向瀏覽器推送數(shù)據(jù),但從實現(xiàn)來看不管是輪詢還是HTTP流,都是瀏覽器先向服務(wù)器發(fā)起請求連接。Web Sockets的全雙工雙向通信也有其特色,以后有時間可以繼續(xù)了解。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持創(chuàng)新互聯(lián)!
當(dāng)前標(biāo)題:Ajax和Comet技術(shù)總結(jié)
網(wǎng)頁鏈接:http://www.rwnh.cn/article2/jjedoc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、響應(yīng)式網(wǎng)站、企業(yè)網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、App開發(fā)、全網(wǎng)營銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)