作為一個前端工作者娶桦,跨域問題應(yīng)該是很常見的贾节,處理方式有很多,下邊來說一說我用到過的處理方式衷畦。
1.什么是跨域
只要協(xié)議栗涂、域名、端口有任何一個不同祈争,都被當(dāng)做不同的域斤程,js不能在不同的域之間進(jìn)行通信和傳輸數(shù)據(jù)。
2.跨域的情況
(1) 用ajax向不同的域請求數(shù)據(jù)
(2) 通過js獲取頁面中不同域的框架中的數(shù)據(jù)(常見iframe)
瀏覽器都有一個同源策略菩混,其限制之一就是不能通過ajax的方法去請求不同源中的文檔忿墅,限制之二是瀏覽器中不同域的框架之間是不能進(jìn)行js的交互操作的。
3.跨域的方法
(1) jsonp跨域
原理:創(chuàng)建<script>標(biāo)簽沮峡,利用src屬性跨域(src屬性可以跨域)疚脐,同樣<img>也可以處理跨域
舉個栗子:
test.html -----> http://a.hao123.com/test.html
ajaxData -----> http://b.hao123.com/list
test.html訪問ajaxData需要跨域
<script src="http://b.haha.com/list?callback=dosomething"></script>
<script type="text/javascript">
function dosomething(jsondata) {
// 處理獲取的json數(shù)據(jù)
}
</script>
通過一個script標(biāo)簽引入一個js文件,當(dāng)js文件載入成功后會把需要的json數(shù)據(jù)作為參數(shù)傳入U(xiǎn)RL中指定的函數(shù)并執(zhí)行此函數(shù)邢疙,因?yàn)閍jaxData被當(dāng)作一個js文件來引入棍弄,所以其返回的數(shù)據(jù)必須是一個能執(zhí)行的js文件,所以需要服務(wù)端的配合才行疟游。
局限性:<1> 需要服務(wù)端配合做處理
<2> jsonp只支持“get”請求呼畸,不支持“post”請求
(2) document.domain來跨越子域
原理:設(shè)置相同的主域
舉個栗子:
有一個頁面,它的地址是 http://a.hao123.com/test.html 颁虐, 在這個頁面里面有一個iframe蛮原,它的src是 http://b.hao123.com/test.html , 很顯然,這個頁面與它里面的iframe框架是不同域的另绩,所以我們是無法通過在頁面中書寫js代碼來獲取iframe中的東西的
<iframe src="http://b.hao123.com/test.html" onload="test()" id="iframe"></iframe>
<script type="text/javascript">
document.domain = "haha.com";
function test() {
// 獲取iframe中的數(shù)據(jù)
var cont = document.getElementById('iframe').contentWindow;
}
</script>
注意: <1> document.domain的設(shè)置是有限制的儒陨,我們只能把document.domain設(shè)置成自身或更高一級的父域送漠,且主域必須相同贞让。
<2> 修改document.domain的方法只適用于不同子域的框架間的交互,對ajax訪問的不適用汁针。
(3) 隱藏iframe做代理跨域
如果你想通過ajax的方法去與不同子域的頁面交互干签,除了使用jsonp的方法外津辩,還可以用一個隱藏的iframe來做一個代理。
原理:讓這個隱藏的iframe載入一個與你想要通過ajax獲取數(shù)據(jù)的目標(biāo)頁面處在相同的域的頁面,所以這個iframe中的頁面是可以正常使用ajax去獲取你要的數(shù)據(jù)的喘沿,然后就是通過修改document.domain的方法闸度,讓我們能通過js完全控制這個iframe,這樣我們就可以讓iframe去發(fā)送ajax請求蚜印,然后收到的數(shù)據(jù)我們也可以獲得了莺禁。
還是方法1中的例子,在test.html中訪問ajaxData
<iframe src="http://b.hao123.com/ajaxProxy.html" onload="test()" id="iframe" style="display:none"></iframe>
<script type="text/javascript>
// 設(shè)置相同的主域
document.domain = 'hao123.com';
iframe = document.getElementById('iframe');
iframe.addEventListener('load',function(e) {
// 1.發(fā)送ajax請求數(shù)據(jù)
// 2.獲取iframe中的數(shù)據(jù)
var cont = iframe.contentWindow;
// 3.數(shù)據(jù)的處理
})
</script>
在梳理一下第3種
<1> test.html中設(shè)置一個隱藏的iframe窄赋,其src為http://b.hao123.com/ajaxProxy.html,與ajaxData處于相同域哟冬,在iframe中訪問ajaxData獲取返回的數(shù)據(jù)
<2> 再利用第二種方法去獲取iframe中的數(shù)據(jù)進(jìn)行處理