由 yangyi 于 2009-05-31 22:28:36 提供 | ||||||||||||||||||||||||||||
2009 年 5 月 25 日 隨著公開提供的 Web 服務(wù) API 不斷增加,現(xiàn)在可以輕松地從不同 Web 源獲取資源并構(gòu)建 mashup —— 只要您能訪問正確的 API 和工具。探究如何能夠結(jié)合高深的跨域調(diào)用技術(shù)(JSONP)和靈活的 JavaScript 庫(jQuery),以快速構(gòu)建強(qiáng)大的 mashup。 Asynchronous JavaScript and XML (Ajax) 是驅(qū)動(dòng)新一代 Web 站點(diǎn)(流行術(shù)語為 Web 2.0 站點(diǎn))的關(guān)鍵技術(shù)。Ajax 允許在不干擾 Web 應(yīng)用程序的顯示和行為的情況下在后臺(tái)進(jìn)行數(shù)據(jù)檢索。使用 不過,由于受到瀏覽器的限制,該方法不允許跨域通信。如果嘗試從不同的域請求數(shù)據(jù),會(huì)出現(xiàn)安全錯(cuò)誤。如果能控制數(shù)據(jù)駐留的遠(yuǎn)程服務(wù)器并且每個(gè)請求都前往同一域,就可以避免這些安全錯(cuò)誤。但是,如果僅停留在自己的服務(wù)器上,Web 應(yīng)用程序還有什么用處呢?如果需要從多個(gè)第三方服務(wù)器收集數(shù)據(jù)時(shí),又該怎么辦? 同源策略阻止從一個(gè)域上加載的腳本獲取或操作另一個(gè)域上的文檔屬性。也就是說,受到請求的 URL 的域必須與當(dāng)前 Web 頁面的域相同。這意味著瀏覽器隔離來自不同源的內(nèi)容,以防止它們之間的操作。這個(gè)瀏覽器策略很舊,從 Netscape Navigator 2.0 版本開始就存在。 克服該限制的一個(gè)相對簡單的方法是讓 Web 頁面向它源自的 Web 服務(wù)器請求數(shù)據(jù),并且讓 Web 服務(wù)器像代理一樣將請求轉(zhuǎn)發(fā)給真正的第三方服務(wù)器。盡管該技術(shù)獲得了普遍使用,但它是不可伸縮的。另一種方式是使用框架要素在當(dāng)前 Web 頁面中創(chuàng)建新區(qū)域,并且使用 克服該限制更理想方法是在 Web 頁面中插入動(dòng)態(tài)腳本元素,該頁面源指向其他域中的服務(wù) URL 并且在自身腳本中獲取數(shù)據(jù)。腳本加載時(shí)它開始執(zhí)行。該方法是可行的,因?yàn)橥床呗圆蛔柚箘?dòng)態(tài)腳本插入,并且將腳本看作是從提供 Web 頁面的域上加載的。但如果該腳本嘗試從另一個(gè)域上加載文檔,就不會(huì)成功。幸運(yùn)的是,通過添加 JavaScript Object Notation (JSON) 可以改進(jìn)該技術(shù)。 JSON 是用于在瀏覽器和服務(wù)器之間交換信息的輕量級數(shù)據(jù)格式(與 XML 相比)。JOSON 依賴于 JavaScript 開發(fā)人員,因?yàn)樗?JavaScript 對象的字符串表示。例如,假設(shè)有一個(gè)含兩個(gè)屬性的 ticker 對象:symbol 和 price。這是在 JavaScript 中定義 ticker 對象的方式:
并且這是它的 JSON 表示方式:
從 參考資料 查找更多有關(guān) JSON 和將其作為數(shù)據(jù)內(nèi)部交換格式的信息。清單 1 定義了一個(gè) JavaScript 函數(shù),調(diào)用該函數(shù)時(shí)會(huì)顯示 IBM 的股價(jià)。(我們沒有詳細(xì)介紹如何將該函數(shù)添加到 Web 頁面)。 清單 1. 定義 showPrice 函數(shù)
可以將 JSON 數(shù)據(jù)作為參數(shù)傳遞,以調(diào)用該函數(shù):
現(xiàn)在準(zhǔn)備將這兩個(gè)步驟包含到 Web 頁面,如清單 2 所示。 清單 2. 在 Web 頁面中包含 showPrice 函數(shù)和參數(shù)
加載頁面后,應(yīng)該看如圖 1 所示的警告。 圖 1. IBM ticker ![]() 至此,本文已展示了如何將靜態(tài) JSON 數(shù)據(jù)作為參數(shù)調(diào)用 JavaScript 函數(shù)。不過,通過在函數(shù)調(diào)用中動(dòng)態(tài)包裝 JSON 數(shù)據(jù)可以用動(dòng)態(tài)數(shù)據(jù)調(diào)用函數(shù),這是一種動(dòng)態(tài) JavaScript 插入的技術(shù)。要查看其效果,將下面一行放入名為 ticker.js 的獨(dú)立 JavaScript 文件中。
現(xiàn)在改變 Web 頁面中的腳本,使其和清單 3 一樣。 清單 3. 動(dòng)態(tài) JavaScript 插入代碼
在清單 3 所示的例子中,動(dòng)態(tài)插入的 JavaScript 代碼位于 ticker.js 文件中,它將真正的 JSON 數(shù)據(jù)作為參數(shù)調(diào)用 前面已經(jīng)提到,同源策略不阻止將動(dòng)態(tài)腳本元素插入文檔中。也就是說,可以動(dòng)態(tài)插入來自不同域的 JavaScript,并且這些域都攜帶 JSON 數(shù)據(jù)。這其實(shí)是真正的 JSONP(JSON with Padding):打包在函數(shù)調(diào)用中的 JSON 數(shù)據(jù)。注意,為了完成該操作,Web 頁面必須在插入時(shí)具有已經(jīng)定義好的回調(diào)函數(shù),也就是我們例子中的 不過,所謂的 JSONP 服務(wù)(或 Remote JSON Service)是一種帶有附加功能的 Web 服務(wù),該功能支持在特定于用戶的函數(shù)調(diào)用中打包返回的 JSON 數(shù)據(jù)。這種方法依賴于接受回調(diào)函數(shù)名作為請求參數(shù)的遠(yuǎn)程服務(wù)。然后該服務(wù)生成對該函數(shù)的調(diào)用,將 JSON 數(shù)據(jù)作為參數(shù)傳遞,在到達(dá)客戶端時(shí)將其插入 Web 頁面并開始執(zhí)行。
從 1.2 版本開始,jQuery 擁有對 JSONP 回調(diào)的本地支持。如果指定了 JSONP 回調(diào),就可以加載位于另一個(gè)域的 JSON 數(shù)據(jù),回調(diào)的語法為: jQuery 自動(dòng)將 ? 替換為要調(diào)用的生成函數(shù)名。清單 4 顯示了該代碼。 清單 4. 使用 JSONP 回調(diào)
為此,jQuery 將一個(gè)全局函數(shù)附加到插入腳本時(shí)需要調(diào)用的窗口對象。另外,jQuery 也能優(yōu)化非跨域調(diào)用。如果向同一個(gè)域發(fā)出請求,jQuery 就將其轉(zhuǎn)化為普通 Ajax 請求。 在上一個(gè)例子中,使用了靜態(tài)文件(ticker.js)將 JavaScript 動(dòng)態(tài)插入到 Web 頁面中。盡管返回了 JSONP 回復(fù),但它不允許您在 URL 中定義回調(diào)函數(shù)名。這不是 JSONP 服務(wù)。因此,如何才能將其轉(zhuǎn)換為真正的 JSONP 服務(wù)呢?可使用的方法很多。這里我們將分別使用 PHP 和 Java 展示兩個(gè)示例。 首先,假設(shè)您的服務(wù)在所請求的 URL 中接受了一個(gè)名為
在這種情況下, 清單 5. 調(diào)用回調(diào)服務(wù)
注意,我們使用 清單 6 顯示了用 PHP 實(shí)現(xiàn)的 JSONP 服務(wù)的一段代碼。 清單 6. 用 PHP 實(shí)現(xiàn)的 JSONP 服務(wù)的代碼片段
清單 7 顯示了具有同樣功能的 Java™ Servlet 方法。 清單 7. 用 Java servlet 實(shí)現(xiàn)的 JSONP 服務(wù)
那么,如果要構(gòu)建 mashup 應(yīng)該怎么辦,是從第三方服務(wù)器收集內(nèi)容,并在單一的 Web 頁面中顯示它們嗎?答案很簡單:您必須使用第三方 JSONP 服務(wù)。這種服務(wù)并不少。 知道如何使用 JSONP 之后,可以開始使用一些現(xiàn)成的 JSONP Web 服務(wù)來構(gòu)建應(yīng)用程序和 mashup。下面為接下來的開發(fā)項(xiàng)目做準(zhǔn)備。(提示:您可以復(fù)制特定的 URL 并將其粘貼到瀏覽器的地址欄,以檢查生成的 JSONP 響應(yīng))。 Digg API:來自 Digg 的頭條新聞:
Geonames API:郵編的位置信息:
Flickr API:來自 Flickr 的最新貓圖片:
Yahoo Local Search API:在郵編為 10504 的地區(qū)搜索比薩:
JSONP 是構(gòu)建 mashup 的強(qiáng)大技術(shù),但不幸的是,它并不是所有跨域通信需求的萬靈藥。它有一些缺陷,在提交開發(fā)資源之前必須認(rèn)真考慮它們。第一,也是最重要的一點(diǎn),沒有關(guān)于 JSONP 調(diào)用的錯(cuò)誤處理。如果動(dòng)態(tài)腳本插入有效,就執(zhí)行調(diào)用;如果無效,就靜默失敗。失敗是沒有任何提示的。例如,不能從服務(wù)器捕捉到 404 錯(cuò)誤,也不能取消或重新開始請求。不過,等待一段時(shí)間還沒有響應(yīng)的話,就不用理它了。(未來的 jQuery 版本可能有終止 JSONP 請求的特性)。 JSONP 的另一個(gè)主要缺陷是被不信任的服務(wù)使用時(shí)會(huì)很危險(xiǎn)。因?yàn)?JSONP 服務(wù)返回打包在函數(shù)調(diào)用中的 JSON 響應(yīng),而函數(shù)調(diào)用是由瀏覽器執(zhí)行的,這使宿主 Web 應(yīng)用程序更容易受到各類攻擊。如果打算使用 JSONP 服務(wù),了解它能造成的威脅非常重要。(參見 參考資料 了解更多信息)。
在該系列的第一篇文章中,我們講解了如何結(jié)合使用 JSONP 和 jQuery 快速構(gòu)建強(qiáng)大的 mashup。主要主題包括:
本系列的下一篇文章將介紹 Yahoo! 查詢語言(YQL),這種單端點(diǎn) JSONP 服務(wù)允許您跨 Web 查詢、過濾和合并數(shù)據(jù)。最后還使用 YQL 和 jQuery 構(gòu)建 mashup 應(yīng)用程序。
|
使用 JSONP 實(shí)現(xiàn)跨域通信,第 1 部分: 結(jié)合 JSONP 和 jQuery 快速構(gòu)建強(qiáng)大的 mashup【轉(zhuǎn)】
只有注冊用戶登錄后才能發(fā)表評論。 | ||
![]() |
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
|
||
相關(guān)文章:
|
||