簡單的來講,出於安全方面的考慮,頁面中的JavaScript沒法訪問其餘服務器上的數據,即「同源策略」。而跨域就是經過某些手段來繞過同源策略限制,實現不一樣服務器之間通訊的效果。 javascript
具體策略限制狀況可看下錶: java
URL | 說明 | 容許通訊 |
http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 容許 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不一樣文件夾 | 容許 |
http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不一樣端口 | 不容許 |
http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不一樣協議 | 不容許 |
http://www.a.com/a.js http://127.0.0.100/b.js |
域名和域名對應ip | 不容許 |
http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不一樣 | 不容許 |
http://www.a.com/a.js http://a.com/b.js |
同一域名,不一樣二級域名(同上) | 不容許 |
http://www.a.com/a.js http://www.b.com/b.js |
不一樣域名 | 不容許 |
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,而JSONP(JSON with Padding)則是JSON 的一種「使用模式」,經過這種模式能夠實現數據的跨域獲取。 ajax
什麼是jsonp格式呢?API原文:若是獲取的數據文件存放在遠程服務器上(域名不一樣,也就是跨域獲取數據),則須要使用jsonp類型。使用這種類型的話,會建立一個查詢字符串參數 callback=? ,這個參數會加在請求的URL後面。服務器端應當在JSON數據前加上回調函數名,以便完成一個有效的JSONP請求。意思就是遠程服務端須要對返回的數據作下處理,根據客戶端提交的callback的參數,返回一個callback(json)的數據,而客戶端將會用script的方式處理返回數據,來對json數據作處理。JQuery.getJSON也一樣支持jsonp的數據方式調用。 json
在同源策略下,在某個服務器下的頁面是沒法獲取到該服務器之外的數據的,但img、iframe、script等標籤是個例外,這些標籤能夠經過src屬性請求到其餘服務器上的數據。利用script標籤的開放策略,咱們能夠實現跨域請求數據,固然,也須要服務端的配合。當咱們正常地請求一個JSON數據的時候,服務端返回的是一串JSON類型的數據,而咱們使用JSONP模式來請求數據的時候,服務端返回的是一段可執行的JavaScript代碼。 跨域
舉個例子,假如須要從服務器(http://www.a.com/user?id=123)獲取的數據以下: 安全
- {"id": 123, "name" : "張三", "age": 17}
那麼,使用JSONP方式請求(http://www.a.com/user?id=123?callback=foo)的數據將會是以下: 服務器
- foo({"id": 123, "name" : "張三", "age": 17});
固然,若是服務端考慮得更加充分,返回的數據可能以下: async
- try{foo({"id": 123, "name" : "張三", "age": 17});}catch(e){}
以PHP爲例,服務端的代碼應該以下: 函數
- $json = json_encode(array("id" => 123, "name" => "張三", "age" => 17));
- if(isset($_GET['callback'])){
- $json = 'try{' . $_GET['callback'] . '(' . $json . ')}catch(e){}';
- }
- echo $json;
這時候咱們只要定義一個foo()函數,並動態地建立一個script標籤,使其的src屬性爲http://www.a.com/user?id=123?callback=foo: jsonp
- <script type="text/javascript" src="http://www.a.com/user?id=123?callback=foo"></script>
即可以使用foo函數來調用返回的數據了。
第一種方法是在ajax函數中設置dataType爲'jsonp':
- $.ajax({
- url: 'http://www.a.com/user?id=123',
async:false,dataType :"jsonp",jsonp:"callbackparam",//服務端用於接收callback調用的function名的參數jsonpCallback:"success_jsonpCallback",//callback的function名稱success :function(json){alert(json);alert(json[0].name);},error:function(){alert('fail');}- });
第二種方法是利用getJSON來實現,只要在地址中加上callback=?參數便可:
- $.getJSON('http://www.a.com/user?id=123&callback=?', function(data){
- //處理data數據
- });
也能夠簡單地使用getScript方法:
- //此時也能夠在函數外定義foo方法
- function foo(data){
- //處理data數據
- }
- $.getScript('http://www.a.com/user?id=123&callback=foo');