JSONP
若是兩個頁面擁有相同的協議,端口(若是指定),和主機,那麼這兩個頁面就屬於同一個源。
同源策略分爲:javascript
DOM
同源策略:禁止對不一樣源頁面DOM
進行操做html
XMLHttpRequest
同源策略:禁止向不一樣源的地址發起HTTP
請求
因而可知,Ajax
禁止跨域。java
JSONP
的原理JSONP
是JSON with Padding
的簡稱,通常用來解決Ajax
跨域的問題。它是這樣產生的:jquery
頁面上調用js
文件時不受跨域的影響,並且,凡是擁有src
屬性的標籤都擁有跨域的能力,好比<script>
、<img>
、<iframe>
。ajax
能夠在遠程服務器上設法把數據裝進js
格式的文件裏,供客戶端調用處理,實現跨域。json
目前最經常使用的數據交換方式是JSON
,客戶端經過調用遠程服務器上動態生成的js
格式文件(通常以JSON
後綴)。跨域
客戶端成功調用JSON
文件後,對其進行處理。瀏覽器
爲了便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP
,該協議的一個要點就是容許用戶傳遞一個callback
參數給服務端,而後服務端返回數據時會將這個callback
參數做爲函數名來包裹住JSON
數據,這樣客戶端就能夠隨意定製本身的函數來自動處理返回數據了。安全
JSONP
的客戶端具體實現2.1 上文已指出,頁面可執行跨域的js
代碼(符合安全策略的),那麼:服務器
<script type="text/javascript"> var localHandler = function (data) { alert('跨域的remote.js文件能夠調用本函數,帶來的數據是:' + data.result); }; </script> <script type="text/javascript" src = "http://remoteserver.com/remote.js"></script>
remote.js
的代碼:
localHandler({ "result": "我是遠程js帶來的數據" });
運行後,成功彈出提示窗口,跨域成功。但問題是,如何讓遠程js
知道它應該調用的本地函數叫什麼名字?
2.2 只要服務端提供的js
腳本是動態生成的就好了,調用者能夠傳一個參數過去告訴服務端本地函數的名字,因而服務端就能夠按照客戶的需求來生成js
腳本並相應了。
var flightHandler = function (data) { alert('你查詢的航班結果是:票價 ' + data.price + '元,餘票' + data.tickets + '張。'); }; var url = 'http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler'; var script = document.createElement('script'); script.setAttribute('src', url); document.getElementsByTagName('head')[0].appendChild(script);
並無直接把遠程js
寫死,而是編碼事項動態查詢。這是JSONP
的核心部分。在調用的url
中傳遞了一個code
參數,告訴服務器要查的是CA1998
次航班的信息,而callback
參數告訴服務器,本地調用的函數叫作flightHandler
。
服務器的flightResult.aspx
生成了如下代碼提供給頁面:
flightHandler({ "code": "CA1998", "price": 1780, "tickets": 5 });
運行一下頁面,成功提示窗口,JSONP
的執行全過程順利完成。
2.3 jQuery
代碼
$(function() { $('button').on('click', function(event) { event.preventDefault(); $.ajax({ type: 'GET', async: false, url: 'http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998', dataType: 'jsonp', jsonp: 'callback', jsonpCallback: 'flightHandler', // 默認爲jQuery自動生成的隨機函數名 success: function (json) { alert('你查詢的航班結果是:票價 ' + json.price + '元,餘票' + json.tickets + '張。'); }, error: function () { alert('fail'); } }); }); });
jQuery
自動生成回調函數並把數據取出來供success
屬性方法來調用。
JSONP
與Ajax
的關係Ajax
與JSONP
這兩種技術看起來很像,目的也同樣,都是請求一個url
,而後把服務器返回的數據進行處理,所以jQuery
等框架都把JSONP
做爲Ajax
的一種形式。
實際上Ajax
與JSONP
有着本質上的不一樣。Ajax
的核心是經過XMLHttpRequest
獲取數據,而JSONP
的核心則是動態添加<script>
標籤來調用服務器提供的js
文件。
Ajax
與JSONP
的區別也不在因而否跨域,Ajax
經過服務端代理也能夠跨域,JSONP
也可獲取同源數據。