什麼是跨域?
發起請求的域名地址和要請求的目標地址不在同一域名下
何時使用跨域?
1、自己的應用程序要請求別人網站上的數據,例如:股票,天氣等
2、當項目太大,前端和後端的應用程序也分屬於不同域名之下
3、自己公司的多個系統互相請求數據
存在的問題: xhr ajax請求不允許跨域
怎樣纔算跨域?
1、同一域名,不同端口,案例:
http://www.domain.com:8000/a.js http://www.domain.com/b.js2、同一域名,不同協議,案例:
http://www.domain.com/a.js http://www.domain.com/b.js 本質端口不同
3、域名和域名對應相同ip,案例:
http://www.domain.com/a.js http://192.168.4.12/b.js 即使統一主機的IP和域名之間相互訪問
4、主語相同,子域不同,案例:
http://www.domain.com/a.js http://x.domain.com/b.js5、主域不同
沒跨域所出的錯
No 'Access-Control-Allow-Origin'
非同源,不允許訪問
如何解決
除了xhr處,有很多元素/屬性可以跨域
比如:img src script的src link的href
方案:
JSONP(JSON with padding填充式JSON)方式跨域(通過script的src進行請求)
方式一:
客戶端:不要使用xhr,使用script請求PHP
<script src="http://localhost/weather.php"></script>
服務器端:不只返回數據,而是將數據填充在一段js代碼中返回(將PHP語句填充成JS語句發送給客戶端)
<?php
$weather = "晴 5~48";
echo "document.write('<h1>".$weather."</h1>')";
問題:服務端返回的語句是固定的,客戶端無法靈活改變
解決:
方式二:
客戶端:定義一個接收參數的函數,使用script請求PHP
<script>
function show(data){
document.write(`<h1>${data}</h1>`);
}
</script>
<script src="http://172.163.7.181/weather.php"></script>
服務器端:只返回一條函數調用的語句,且函數名與客戶端函數名保持一致
<?php
$weather = "晴天 5~80度";
echo "show('".$weather."')";
問題:函數名必須和服務端統一
解決:
方式三:
客戶端:定義一個接收參數的函數,用script請求PHP,攜帶一個參數callback,值爲函數名
<script>
function display(data){
document.write(`<h1>${data}</h1>`);
}
</script>
<script src="http://172.163.7.181/weather.php?callback=display"></script>
服務器端:從請求中獲得callback參數名(函數名),將函數名和數據拼接位一條調用JS語句
<?php
@$callback = $_REQUEST["callback"];
$weather = "*";
echo "$callback('".$weather."')";
問題:只能在頁面加載時運行,無法自行選擇觸發時間
解決:
方式四:
客戶端:動態創建script添加到頁面,用完自動刪除script
<script>
function display(data){
alert(data);
$("script:last").remove();
}
$("#btnWeather").click(function(){
$(`<script src="http://172.163.7.181/weather.php?callback=display"><\/script>`).appendTo(document.body);
});
</script>
服務器端:從請求中獲得callback參數值(函數名),將函數名和數據拼接位一條調用的JS語句
<?php
@$callback = $_REQUEST["callback"];
$weather = "*";
echo "$callback('".$weather."')";
$.ajax支持JSONP
加入dataType:"jsonp"
幾乎所有項目AJAX中都需要dataType:"jsonp"
原理:調用時隨機自動生成函數名,並自動在head中添加script將函數名作爲值進行傳遞,調用接收後自動消失
$.ajax({
type:"get",
url:"http://127.0.0.1/weather.php",
dataType:"jsonp",
//127.0.0.1 "http://localhost/weather.php" 172.163.7.181
success:function(data){
document.write(`<h1>${data}</h1>`);
}
})
2、服務端跨域
修改響應頭,允許添加跨域的地址
header("Access-Control-Allow-Origin:*/請求發來的地址"); 允許一切
使用較少,比較危險