Asynchronous JavaScript and XML (Ajax ) 是驅動新一代 Web 站點(流行術語爲 Web 2.0 站點)的關鍵技術。Ajax 容許在不干擾 Web 應用程序的顯示和行爲的狀況下在後臺進行數據檢索。使用 XMLHttpRequest
函數獲取數據,它是一種 API,容許客戶端 JavaScript 經過 HTTP 鏈接到遠程服務器。Ajax 也是許多 mashup 的驅動力,它可未來自多個地方的內容集成爲單一 Web 應用程序。javascript
不過,因爲受到瀏覽器的限制,該方法不容許跨域通訊。若是嘗試從不一樣的域請求數據,會出現安全錯誤。若是能控制數 據駐留的遠程服務器而且每一個請求都前往同一域,就能夠避免這些安全錯誤。可是,若是僅停留在本身的服務器上,Web 應用程序還有什麼用處呢?若是須要從多個第三方服務器收集數據時,又該怎麼辦?php
同源策略阻止從一個域上加載的腳本獲取或操做另外一個域上的文檔屬性。也就是說,受到請求的 URL 的域必須與當前 Web 頁面的域相同。這意味着瀏覽器隔離來自不一樣源的內容,以防止它們之間的操做。這個瀏覽器策略很舊,從 Netscape Navigator 2.0 版本開始就存在。java
克服該限制的一個相對簡單的方法是讓 Web 頁面向它源自的 Web 服務器請求數據,而且讓 Web 服務器像代理同樣將請求轉發給真正的第三方服務器。儘管該技術得到了廣泛使用,但它是不可伸縮的。另外一種方式是使用框架要素在當前 Web 頁面中建立新區域,而且使用 GET
請求獲取任何第三方資源。不過,獲取資源後,框架中的內容會受到同源策略的限制。jquery
克服該限制更理想方法是在 Web 頁面中插入動態腳本元素,該頁面源指向其餘域中的服務 URL 而且在自身腳本中獲取數據。腳本加載時它開始執行。該方法是可行的,由於同源策略不阻止動態腳本插入,而且將腳本看做是從提供 Web 頁面的域上加載的。但若是該腳本嘗試從另外一個域上加載文檔,就不會成功。幸運的是,經過添加 JavaScript Object Notation (JSON) 能夠改進該技術。ajax
一、什麼是JSONP?json
要了解JSONP,不得不提一下JSON,那麼什麼是JSON ?跨域
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.瀏覽器
JSONP(JSON with Padding)是一個非官方的協議,它容許在服務器端集成Script tags返回至客戶端,經過javascript callback的形式實現跨域訪問(這僅僅是JSONP簡單的實現形式)。安全
二、JSONP有什麼用?
因爲同源策略的限制,XmlHttpRequest只容許請求當前源(域名、協議、端口)的資源,爲了實現跨域請求,能夠經過script標籤實現跨域請求,而後在服務端輸出JSON數據並執行回調函數,從而解決了跨域的數據請求。
三、如何使用JSONP?
下邊這一DEMO其實是JSONP的簡單表現形式,在客戶端聲明回調函數以後,客戶端經過script標籤向服務器跨域請求數據,而後服務端返回相應的數據並動態執行回調函數。
HTML代碼 (任一 ):
或者
JavaScript的連接,必須在function的下面。
服務端PHP代碼 (services.php):
若是將上述JS客戶端代碼用jQuery的方法來實現,也很是簡單。
$.getJSON
$.ajax
$.get
客戶端JS代碼在jQuery中的實現方式1:
客戶端JS代碼在jQuery中的實現方式2:
客戶端JS代碼在jQuery中的實現方式3:
其中 jsonCallback 是客戶端註冊的,獲取 跨域服務器 上的json數據 後,回調的函數。
http://crossdomain.com/services.php?callback=jsonpCallback
這個 url 是跨域服務 器取 json 數據的接口,參數爲回調函數的名字,返回的格式爲
Jsonp原理:
首先在客戶端註冊一個callback, 而後把callback的名字傳給服務器。
此時,服務器先生成 json 數據。
而後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的參數 jsonp.
最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標籤,並執行返回的 javascript 文檔,此時數據做爲參數,傳入到了客戶端預先定義好的 callback 函數裏.(動態執行回調函數)
使用JSON的優勢在於:
JSON也有一些劣勢:
儘管如此,JSON的優勢仍是很明顯的。他是Ajax數據交互的很理想的數據格式。
JSONP 是構建 mashup 的強大技術,但不幸的是,它並非全部跨域通訊需求的萬靈藥。它有一些缺陷,在提交開發資源以前必須認真考慮它們。
第一,也是最重要的一點,沒有關於 JSONP 調用的錯誤處理。若是動態腳本插入有效,就執行調用;若是無效,就靜默失敗。失敗是沒有任何提示的。例如,不能從服務器捕捉到 404 錯誤,也不能取消或從新開始請求。不過,等待一段時間尚未響應的話,就不用理它了。(將來的 jQuery 版本可能有終止 JSONP 請求的特性)。
JSONP 的另外一個主要缺陷是被不信任的服務使用時會很危險。由於 JSONP 服務返回打包在函數調用中的 JSON 響應,而函數調用是由瀏覽器執行的,這使宿主 Web 應用程序更容易受到各種攻擊。若是打算使用 JSONP 服務,瞭解它能形成的威脅很是重要。