同源策略引起對跨域jsonp跨域的理解

     一,同源策略其實網絡的安全基石,既:http://www.baidu.com:80協議(http或者HTTPS或者ws或者wss)、域名(www.baidu.com)、端口(默認80,能夠不寫 https默認是443端口)相同。防止一些信息被人盜取或者破壞,具體的概念在這裏就不詳細述說了,你們可參考阮一峯大師的文章(http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html)。javascript

    二,你們有沒有注意下面的這種狀況:html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		img{
			width:200px;
			height: 100px;
		}
	</style>
</head>
<body>
	<img src="https://mdn.mozillademos.org/files/12676/star.svg" alt="">
</body>
</html>

  上面代碼紅色區域src 引用的是https協議下的一個網路圖片,可是你把代碼在本地瀏覽器打開的時候,也能夠請求到圖片,看一下圖片的對比。也就是說下面兩個連接是在不一樣域狀況下打開的,可是能夠跨域請求到想要的圖片。也就是說咱們能夠利用src的屬性進行跨域請求數據,也就是說 script標籤也能夠跨域請求相應的資源,如:<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>前端

 

 三,先讓你們看代碼<!DOCTYPE html>java

<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		img{
			width:200px;
			height: 100px;
		}
	</style>
  <script>
     function a(){
      alert(1)
     } </script> </head> <body> <script> a(); </script> </body> </html>

  你們用瀏覽器打開頁面,會看到頁面彈出了1,注意看標記爲紅色的區域。是在兩個不一樣的script一個賦值一個請求,這樣是能夠請求道的。說這個的目的是爲了爲下面封裝jsonp 作解釋。jquery

四,先看封裝好的jsop函數:原理:前端定義個全局的函數,動態建立script,利用src去請求後臺的資源,只是後臺返回的是一個參數爲前端所需數據前端全局函數調用。看下圖:請求道的是一個函數的調用。json


 


 

下面我對代碼裏①到⑦作一一的解釋。跨域

①:cbName是爲了跟後臺建立一個相應的規則協議,跨域請求的時候,容許用戶傳遞一個callback參數給服務端,而後服務端返回數據時會將這個callback參數做爲函數名來包裹住JSON數據,客戶端能夠隨意定製本身的函數(fnName)來自動處理返回數據了。 瀏覽器

②:每次請求相同的src瀏覽器會緩衝,因此在uri後面添加時間戳,防止二次請求的時候,返回不是最新想要的數據。安全

③:url路徑不容許帶有小數點,因爲時間戳帶有小數點,要把小數點替換成空。網絡

④:src去請求數據時 能夠自定義取數據的時間,超過規定的時間,就定義爲請求超時。請求超時就不要再讓window.fn繼續執行處理數據,window[fnName] = null。

⑤:跨域請求過來的是自定義的回調函數的調用,當回調調用成功後,也就是調用了全局的window[fnName]函數(這函數裏也能夠繼續回調(success)函數)來處理數據,達到本身想要的數據類型或者舍取。因爲獲取成功後相應超時的限制意義就不存在了,要把定時器關閉。並把建立好的script對象刪除。

<script>

fnName (json) {//window下的函數

  ......XXXX

}

</script>

再在動態建立的srcpt裏,請求到後臺返回數據(數據爲:函數的直接調用)。

<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=%E7%8E%8B%E6%B5%A9&cb=jsonp_p08777009389580372#"></script>   ===  window.fnName();

⑥:拼接url,到達協議的要求,即:後臺返回jsonp回調函數的要求:關鍵字、cbName及其餘請求參數。

⑦:dom操做建立添加script標籤,動態請求數據,成功後直接刪除。

function jsonp(options){
	if(!options.url){return;}
	options = options||{};
	options.data = options.data||{};
	options.cbName = options.cbName||'cb';//
	options.timeout = options.timeout||10000;
	var fnName = 'jsonp_p'+Math.random();//
	var fnName = fnName.replace('.','');//
	var timer = setTimeout(function(){//
		options.error&&options.error();
		window[fnName] = null;
	},options.timeout);
	
	window[fnName] = function(json){ //
		options.success&&options.success(json);
		clearTimeout(timer);
		document.getElementsByTagName('head')[0].removeChild(oS);
	};
	//cb = show
	options.data[options.cbName] = fnName;
	var arr = [];
	for(var name in options.data){//
		arr.push(name+'='+options.data[name]);
	}
	
	var oS = document.createElement('script');//
	oS.src = options.url+'?'+arr.join('&');	
	document.getElementsByTagName('head')[0].appendChild(oS);
}

  五,以上就是本人對jsonp的理解,因爲小生纔能有限,寫的不到位的地方請大神多多指教,本人將不吝賜教,謝謝!

相關文章
相關標籤/搜索