深入理解前端跨域方法和原理
阿新 • • 發佈:2019-01-07
//本域為baidu.com <script> function JSONP_getUsers(users){ console.dir(users); } </script> //載入google.com的getUsers.php <script src="http://www.google.com/getUsers.php"></script>
<?php>
echo 'JSONP_getUsers(["paco","john","lili"])';//返回一個js函式的呼叫
?>
<script src="http://www.google.com/getUsers.php?flag=do&time=1"></script>。
JSONP易於實現,但是也會存在一些安全隱患,如果第三方的指令碼隨意地執行,那麼它就可以篡改頁面內容,截獲敏感資料。但是在受信任的雙方傳遞資料,JSONP是非常合適的選擇。可以看出來JSONP跨域一般用於獲取其他域的資料。
<?php>
echo 'var users=["paco","john","lili"]';//返回一個js變數users
?>
那麼在本域下就可以取到data變數,這裡需要注意判斷script節點是否載入完畢,如:
js.onload = js.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
console.log(users);//此處取出其他域的資料
js.onload = js.onreadystatechange = null;
}
};
header("Access-Control-Allow-Origin: http://www.baidu.com");//表示允許baidu.com跨域請求本檔案
try {
parent.location.hash = 'data';
} catch (e) {
// ie、chrome的安全機制無法修改parent.location.hash,
var ifrproxy = document.createElement('iframe');
ifrproxy.style.display = 'none';
ifrproxy.src = "http://www.baidu.com/proxy.html#data";
document.body.appendChild(ifrproxy);
}
//因為parent.parent(即baidu.com/a.html)和baidu.com/proxy.html屬於同一個域,所以可以改變其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);
window.onload = function() {
var ifr = document.getElementById('ifr');
var targetOrigin = "http://www.google.com";
ifr.contentWindow.postMessage('hello world!', targetOrigin);
};
var onmessage = function (event) {
var data = event.data;//訊息
var origin = event.origin;//訊息來源地址
var source = event.source;//源Window物件
if(origin=="http://www.baidu.com"){
console.log(data);//hello world!
}
};
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', onmessage, false);
} else if (typeof window.attachEvent != 'undefined') {
//for ie
window.attachEvent('onmessage', onmessage);
}
同理,也可以B頁面傳送訊息,然後A頁面監聽並接受訊息。