我們在開發中,經常會遇到跨域請求數據問題,那么什么是跨域呢?跨域就是js在不用域之間的數據傳輸或者通信,比如你在使用ajax從另外一個域請求數據,或者你的頁面引入了iframe,要從iframe中獲取數據的時候,就是跨域。簡單一點的說,判斷是否跨域,就看協議、域名、端口,這三個中只要有一個不同,就都屬於不同的域。
<script> function do(jsondata){ //處理數據 } </script> <script src="http://exampleData/data.php?callback=do"></script>
由此就可以看出jsonp的原理就是利用script引入js文件,文件加載成功后執行url中指定的函數,我們需要獲取的json數據將會作為參數傳入。不過如果數據地址是別人的文件,自己無法操控,那么就得按照提供數據的一方的數據模式來處理。所以使用jsonp方法處理跨域,是需要服務器端的配合。
也可以使用jquery封裝$.getJSON()的方法,這個方法很便利,看一下代碼:
<script> $.getJSON('http://exampleData/data.php?callback=?’,function(jsondata){ //處理數據 }); </script>
jquery會自動生成一個全局函數來替換callback=?中的問號,獲取到數據后又會自動銷毀。$.getJSON方法會自動判斷是否跨域,不跨域,就調用普通的ajax方法;跨域,則會以異步加載js文件的形式來調用jsonp的回調函數。
二、使用window.name解決跨域
window.name的性質是,在一個窗口的生命周期內,窗口載入的所有頁面都是共享一個name,而且對name都有讀寫的權限。而且name並不會因為有新頁面的載入而重置,是一直存在在窗口中的。即使是在一個頁面中載入了另外一個不同域的頁面,這個name的值只要之前沒有修改,那也是不會變的。
那么就可以利用這特性來解決跨域問題。
比如從www.example.com/a.html中獲取www.data.com/b.html中的數據,我們可以用一個隱藏的iframe標簽來加載b頁面,再在a頁面里獲取iframe的數據。
首先要在b.html中設置一下:
<script>
window.name="a頁面需要獲取的json數據或者字符串";
</script>
a.html中的代碼為:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>解決跨域問題</title> <style type="text/css"> #ifarme{ display:none; } </style> </head> <body> <iframe src="http://www.data.com/b.html" frameborder="0" onload="getData()" id="ifarme"></iframe> </body> <script type="text/javascript"> function getData(){ var iframe = document.getElementById("iframe"); iframe.onload = function(){ var data = iframe.contentWindow.name; console.log(data); } ifarme.src="about:blank";//這里的src的頁面可以隨意設置為與a.html同源的頁面,空白頁about:blank也行。只有同源,a.html才能訪問到iframe里面的東西。 } </script> </html>
跨域的原理基本就是這樣,可以根據自己的需求改寫封裝。作為數據中轉的ifame,可以在獲取完數據之后銷毀。