ajax跨域問題我只學一種解決方案

Ajax跨域問題的jsonp解決方案javascript

在前端咱們常常會使用Ajax來向服務器發送請求和接收服務器響應回來的數據,通常來講在同一個服務器的數據來往是沒有什麼問題的,可是有時使用Ajax請求數據並不侷限於同一個服務器,跨服務器請求就會遇到跨域問題,下面咱們探討一下跨域問題是怎麼產生的,最優的解決方案是什麼?php

同源策略

同源策略是瀏覽器的一種安全策略,是爲了保護本地數據不被從其餘服務器獲取回來的數據污染,從而拒絕接受非本服務器響應回來的數據.這樣的後果就是咱們能成功的向其餘的服務器發送數據請求,對方也能成功響應並返回數據,html

可是,就是沒有辦法接受數據,由於瀏覽器攔截了.前端

這裏解釋一下"同源"的概念:java

協議,域名,端口都一致視爲同源,有其中一個不一樣則爲不一樣源jquery

跨域問題

上面已經解釋了什麼是同源,能夠理解爲同源即同域,若是在非同源的基礎上,想要進行數據來往,這時就會出現咱們所說的跨域問題web

怎麼解決Ajax的跨域問題

一共有六種方案:ajax

  • jsonp
  • document.domain+iframe
  • document.hash+iframe
  • window.name+iframe
  • window.postMessage
  • flash等第三方插件

注意:我下面要講的解決方案是jsonp,在講jsonp以前我先講基礎的同源的jQuery的Ajax的寫法json

同源的jQuery的Ajax的實現

1.環境

phpstudyapi

2.目錄結構

3.index.html文件
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">獲取數據</button>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { $.ajax({ type: "get", url: "./data.php", dataType:"json", success: function(data) { //var data=JSON.parse(data); console.log(data.username);//zhangsan console.log(data.age);//12 }, error: function() { console.log("獲取失敗"); } }); }) }) </script>
	</body>
</html>

複製代碼
4.data.php文件
<?php
	$arr=["username"=>"zhangsan","age"=>12];
	echo json_encode($arr);
?>
複製代碼

運行結果

注意:

  • 上面的代碼在同源的狀況下可以成功請求到data.php,併成功打印出數據

  • //jQuery中通常不須要json數組轉化爲對象,只須要指定數據的類型是json類型便可
    dataType:"json"//默認爲文本型
    複製代碼

跨域的jQuery的Ajax

爲了實現Ajax的跨域請求,須要將上面例子的基礎上,將index.html文件中Ajax請求的路徑改成不一樣域名的網站,我在phpstudy環境中映射了一個目錄並指定一個域名,下面的例子咱們就來跨域訪問該目錄下的data.php文件

修改index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">獲取數據</button>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { $.ajax({ type: "get", url: "http://www.web2.com/data.php", dataType:"json", success: function(data) { //var data=JSON.parse(data); console.log(data.username);//zhangsan console.log(data.age);//12 }, error: function() { console.log("獲取失敗"); } }); }) }) </script>
	</body>
</html>
複製代碼

data.php文件

<?php
	$arr=["username"=>"zhangsan","age"=>12];
	echo json_encode($arr);
?>
複製代碼

運行結果

從上面的結果來看,跨域請求數據成功,對方響應也成功了,可是被瀏覽器攔截了,這就是典型的跨域問題

下面咱們來解決這個問題,並能在前臺成功讀取返回來的值

JSONP的實現

jsonp這種解決跨域問題方案一共有兩種方法

  • 靜態script標籤的src屬性進行跨域請求
  • 動態建立script標籤,經過標籤的src屬性進行跨域請求
靜態script標籤的src屬性進行跨域請求

在前端的頁面中將跨域的請求的URL賦值給script標籤的src屬性

<script src="http://www.web2.com/data.php"></script>
複製代碼
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">獲取數據</button>
		<script src="http://www.web2.com/data.php"></script>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { console.log(temp); }) }) </script>
	</body>
</html>

複製代碼

data.php

<?php
	//echo "var temp=111";//傳單個值
	$arr=["username"=>"zhangsan","age"=>12];//項目中經常傳數組
	$arr=json_encode($arr);
	echo "var temp=".$arr;
?>
複製代碼

不難發現這種傳值的方式有些麻煩,下面介紹動態建立script標籤,經過標籤的src屬性進行跨域請求

動態建立script標籤,經過標籤的src屬性進行跨域請求

原生js寫法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<script type="text/javascript"> //動態建立 var script=document.createElement("script"); script.src="http://www.web2.com/data.php?callback=gdata"; var head=document.getElementsByTagName('head')[0]; head.appendChild(script); function gdata(data){ console.log(data.username); console.log(data.age); } </script>
	</body>
</html>
複製代碼

data.php

<?php
	$arr=["username"=>"zhangsan","age"=>12];
	$arr=json_encode($arr);
	$cb=$_GET['callback'];
	echo $cb.'('.$arr.')';//調用回調函數,注意拼接的方式,
?>
複製代碼

注意: 在上面的這種方法中,回調函數名字默認是callback,JQuery官方文檔有說明,固然也能夠是其餘名字,這個名字由後臺人員定義,再告訴前端人員,不然前端人員將沒法使用正確的回調函數名獲取值 咱們知道,在實際的項目中,咱們常常使用的是jQuery的寫法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
	</head>
	<body>
		<button class="btn">獲取數據</button>
		<script type="text/javascript"> $(function() { $(".btn").click(function() { $.ajax({ type: "get", url: "http://www.web2.com/data.php", dataType:"jsonp",//注意類型爲jsonp success: function(data) { console.log(data.username);//zhangsan console.log(data.age);//12 }, error: function() { console.log("獲取失敗"); } }); }) }) </script>
	</body>
</html>
複製代碼

到此爲止,咱們就講完了Ajax跨域請求的jsonp解決方案,可是在實際的調用別人的api時還會有其餘要注意的問題,好比須要在發送請求時同時將使用api的密鑰發送過去

相關文章
相關標籤/搜索