jQuery中利用JSONP解決AJAX跨域問題

什麼是跨域?

簡單的來講,出於安全方面的考慮,頁面中的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
不一樣域名 不容許

什麼是JSONP?

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

JSONP跨域的原理

在同源策略下,在某個服務器下的頁面是沒法獲取到該服務器之外的數據的,但img、iframe、script等標籤是個例外,這些標籤能夠經過src屬性請求到其餘服務器上的數據。利用script標籤的開放策略,咱們能夠實現跨域請求數據,固然,也須要服務端的配合。當咱們正常地請求一個JSON數據的時候,服務端返回的是一串JSON類型的數據,而咱們使用JSONP模式來請求數據的時候,服務端返回的是一段可執行的JavaScript代碼。 跨域

舉個例子,假如須要從服務器(http://www.a.com/user?id=123)獲取的數據以下: 安全

 
  1. {"id": 123, "name" : "張三", "age": 17}

那麼,使用JSONP方式請求(http://www.a.com/user?id=123?callback=foo)的數據將會是以下: 服務器

 
  1. foo({"id": 123, "name" : "張三", "age": 17});

固然,若是服務端考慮得更加充分,返回的數據可能以下: async

 
  1. try{foo({"id": 123, "name" : "張三", "age": 17});}catch(e){}

PHP爲例,服務端的代碼應該以下: 函數

 
  1. $json = json_encode(array("id" => 123, "name" => "張三", "age" => 17));
  2. if(isset($_GET['callback'])){
  3. $json = 'try{' . $_GET['callback'] . '(' . $json . ')}catch(e){}';
  4. }
  5. echo $json;

這時候咱們只要定義一個foo()函數,並動態地建立一個script標籤,使其的src屬性爲http://www.a.com/user?id=123?callback=foo: jsonp

 
  1. <script type="text/javascript" src="http://www.a.com/user?id=123?callback=foo"></script>

即可以使用foo函數來調用返回的數據了。

jQuery中如何經過JSONP來跨域獲取數據

第一種方法是在ajax函數中設置dataType爲'jsonp':

 
  1. $.ajax({
  2. url: 'http://www.a.com/user?id=123',
  3. 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');
        }
  4. });

第二種方法是利用getJSON來實現,只要在地址中加上callback=?參數便可:

 
  1. $.getJSON('http://www.a.com/user?id=123&callback=?', function(data){
  2. //處理data數據
  3. });

也能夠簡單地使用getScript方法:

 
  1. //此時也能夠在函數外定義foo方法
  2. function foo(data){
  3. //處理data數據
  4. }
  5. $.getScript('http://www.a.com/user?id=123&callback=foo');
相關文章
相關標籤/搜索