跨域請求 JSONP

首先,我們得了解一個概念,叫同源策略(same-origin policy).
比如,我們在寫自己公司的一個網站,然後我們需要從淘寶獲取商品信息,比如: https://www.taobao.com/goods,我們肯定拿不到,因爲存在這同源策略,一下是同源策略的定義.

不同域的客戶端腳本沒有授權的情況下不能讀寫對方的資源。

只有在同協議,同域名,同端口 下才能成爲同域。
在這裏插入圖片描述
比如,以上例子可以看出,只有最後一個跟http://ke.qq.com同域,也就是說可以直接訪問獲取數據。

有常用的3中繞開這個限制的方法

  • CORS(cross domain resourse sharing)
  • JSONP(json with padding)
  • 藉助iframe跨域

下面着重來介紹一下JSONP.
首先,我們得了解script標籤是可以越過這個限制的,我們在寫Jquery的時候,就會用到谷歌的Jquery的cdn,比如一下代碼。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

只要我們引用過來,我們的網站裏就可以使用Jquery,是因爲script標籤不受同源策略的限制,因此我們也可以受這個啓發。
在JSONP,當我們給服務器發用script標籤發請求的時候我們傳特殊的參數來說明一下我們頁面的情況,這樣的話,服務器會客戶端可以接受的形式來返回。
比如,服務器期望接受一個叫callback來使JSONP可行,你的請求應該使這樣的。

http://www.example.net/sample.aspx?callback=mycallback

如果沒有JSONP,服務器應該這樣返回,比如:

 { foo:'bar' }

但有了JSONP,有了請求時候的一個參數 callback,服務器會把以不同的形式返回,比如:

 mycallback({foo:'bar'});

可以看到這個返回會調用我們指定的方法,因此,在我們的頁面裏,我們可以定義一下函數:

mycallback = function(data){
 alert(data.foo);
};

然後返送請求的時候,我們頁面寫的方法會被執行,跨域完成。
下面是用了JSONP的實際例子:

<!DOCTYPE html> 
<html> 
<body> 
   <p id="paragraphElement"></p> 

   <!-- The server returns a call to the callback function 
   (processData) that will handle the JSON data -->
   <script> 
   	function processData(myObj) { 
   	console.log(myObj); 
   	var para= document.getElementById("paragraphElement"); 
   	for(var i=0; i<myObj.resultCount; i++){ 
   		para.innerHTML= para.innerHTML + myObj.results[i].trackName 
   						+ "<br>" ; 
   		} 
   	} 
   </script> 
   
<!-- Calling the iTunes API to search for Jack Johnson's songs and return 
   	the first five items -->
   <script src="https://itunes.apple.com/search?term=jack+johnson&limit=5
   &callback=processData"></script> 
</body> 
</html>					 

在實際開發的時候不能自己填寫上去,必須得自動化,下面是簡單的自動化構造JSONP的代碼.

<!DOCTYPE html>
<html>
   <head>
   	<meta charset="utf-8">
   	<title></title>
   </head>
   <body>
   	<script type="text/javascript">
   		window.onload=createScriptDynamically();
   		function createScriptDynamically(){
   			const url="https://itunes.apple.com/search?term=taylor+swift&limit=5&callback=processData";
   			let scriptElement=document.createElement('script');
   		    scriptElement.setAttribute('src',url);
   			scriptElement.setAttribute('id','jsonP');
   			let head=document.getElementsByTagName('head')[0];
              head.appendChild(scriptElement);
   		   console.log(head);
   		}
   		
   		function processData(data){
   			console.log(data);
   		}
   	</script>
   </body>
</html>

更多請參考

發佈了87 篇原創文章 · 獲贊 19 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章