【AngularJs】---JSONP跨域訪問數據傳輸

你們會天然想到只有一個字母之差的JSON吧~javascript

JSON(JavaScript Object Notation)和JSONP(JSON with Padding)雖然只有一個字母的差異,但其實他們根本不是一回事兒java

JSON是一種數據交換格式,而JSONP是一種依靠開發人員的聰明才智創造出的一種非官方跨域數據交互協議。咱們拿最近比較火的諜戰片來打個比方,JSON是地下黨們用來書寫和交換情報的「暗號」,而JSONP則是把用暗號書寫的情報傳遞給本身同志時使用的接頭方式。看到沒?一個是描述信息的格式,一個是信息傳遞雙方約定的方法。git

 

瀏覽器是存在同源策略這個機制的,在全局層面禁止了頁面加載或執行與自身來源不一樣的域的任何腳本。github

JSONP是一種能夠繞過瀏覽器的安全限制,從不一樣的域請求數據的方法。web

 

Web頁面上調用js文件時則不受是否跨域的影響(不只如此,咱們還發現凡是擁有」src」這個屬性的標籤都擁有跨域的能力,好比<script>、<img>、<iframe>);ajax

若是想經過純web端(ActiveX控件、服務端代理、屬於將來的HTML5之Websocket等方式不算)跨域訪問數據就只有一種可能,那就是在遠程服務器上設法把數據裝進js格式的文件裏,供客戶端調用和進一步處理;JSON的純字符數據格式能夠簡潔的描述複雜數據,被js原生支持,因此在web客戶端經過與調用腳本如出一轍的方式,來調用跨域服務器上動態生成的js格式文件(通常以JSON爲後綴),顯而易見,服務器之因此要動態生成JSON文件,目的就在於把客戶端須要的數據裝入進去。爲了便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP,該協議的一個要點就是容許用戶傳遞一個callback參數給服務端,而後服務端返回數據時會將這個callback參數做爲函數名來包裹住JSON數據,這樣客戶端就能夠隨意定製本身的函數來自動處理返回數據了。json

 

JSONP的原理是經過<script>標籤發起一個GET請求來取代XHR請求。JSONP生成一個<script>標籤並插到DOM中,而後瀏覽器會接管並向src屬性所指向的地址發送請求。後端

當服務器返回請求時,響應結果會被包裝成一個JavaScript函數,並由該請求所對應的回調函數調用。api

AngularJS在$http服務中提供了一個JSONP輔助函數。經過$http服務的jsonp方法能夠發送請求,以下所示:跨域

     $http .jsonp("https://api.github.com?callback=JSON_CALLBACK") .success(function(data) { 

  // 數據
});

當請求被髮送時,AngularJS會在DOM中生成一個以下所示的<script>標籤:

  <script src="https://api.github.com?callback=angular.callbacks._0" type="text/javascript"></script> 

注意,JSON_CALLBACK被替換成了一個特意爲此請求生成的自定義函數。當支持JSOPN的服務器返回數據時,數據會被包裝在由AngularJS生成的具名函數angular.callbacks._0中在這個例子中,GitHub服務器會返回包含在回調函數中的JSON數據,響應看起來以下所示: 

 // 簡寫  

  angular.callbacks._0({ 

    'meta': {
      'X-RateLimit-Limit': '60',
      'status': 200
    },
    'data': {
      'current_user_url': 'https://api.github.com/user'
    }
  })
當AngularJS調用指定的回調函數時會對$http的promise對象進行resolve。當咱們本身開發支持JSONP的後端服務時,要確保響應的數據被包含在請求所指定的回調函數中。使用JSONP須要意識到潛在的安全風險。首先,服務器會徹底開放,容許後端服務調用應用中的任何JavaScript。不受咱們控制的外部站點(或者蓄意攻擊者)能夠隨時更改腳本,使咱們的整個站點變得脆弱。服務器或中間人有可能會將額外的JavaScript邏輯返回給頁面,從而將用戶的隱私數據暴露出來。因爲請求是由<script>標籤發送的,因此只能經過JSONP發送GET請求。而且腳本的異常也很難處理。使用JSONP必定要謹慎,同時只跟信任並能夠控制的服務器進行通訊。

 

一句話就是利用script標籤繞過同源策略,得到一個相似這樣的數據,jsonpcallback是頁面存在的回調方法,參數就是想獲得的json。

 

 

Jquery中jsonp的使用

 

myUrl = "http://localhost:8090/api/test";

$.ajax({
  type:"GET",
  url:myUrl,
  dataType:"jsonp",
  jsonp:"callback",
  jsonpCallback:"jsonpCallback",
  success:function(data){
    alert(data.msg);
  } }); function jsonpCallback(data){   alert(data); }
1.jsonp只能使用get請求,解決同源問題,返回javascript代碼,由於請求javascript文件是沒有同源問題的。
2.當請求數據類型爲jsonp時,會將callback=jsonpCallback加在url上,http://localhost:8090/api/testcallback=jsonpCallback
3.前臺javascript中定義jsonpCallback函數,此函數必須定義在window下,也就是全局的函數,不然找不到。
4.後臺獲取請求的callback參數值jsonpCallback,返回字符串"jsonpCallback(result)",result爲返回結果。
5.請求返回的是script tag,首先會調用jsonpCallback函數,不論是否找到該函數,都會調用success函數。
6.若是沒有定義jsonp和jsonpCallback,jsonp默認爲"callback",jsonpCallback會是Jquery自動生成的函數名。

 

angularJS中jsonp的使用

myUrl = "http://localhost:8090/api/test?callback=JSON_CALLBACK";

$http.jsonp(myUrl).success(  function(data){
    alert(data);
  }
);

1.angularJS中使用$http.jsonp函數
2.指定callback和回調函數名,函數名爲JSON_CALLBACK時,會調用success回調函數,JSON_CALLBACK必須全爲大寫。
3.也能夠指定其它回調函數,但必須是定義在window下的全局函數。
4.url中必須加上callback
5.當callback爲JSON_CALLBACK時,只會調用success,即便window中有JSON_CALLBACK函數,也不會調用該函數。
相關文章
相關標籤/搜索