歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

利用location.hash+iframe跨域獲取數據詳解

前言

  如果看懂了前文利用window.name+iframe跨域獲取數據,那麼此文也就很好理解了。一樣都是動態插入一個iframe,然後把iframe的src指向服務端地址,而服務端同樣都是輸出一段js代碼,同樣都是利用和子窗口之間的通信完成數據傳輸,同樣要針對同源策略做出處理。

location.hash和錨點

  要理解location.hash+iframe跨域獲取數據的機制,先得知道什麼是location.hash,樓主買一送一,把錨點也一起介紹了。

  其實錨點很簡單,也相信大家都有用過。納尼,你布吉島?小看段代碼就略知一二了(代碼效果猛戳這裡):

<a href='#1'>red</a>
<a href='#2'>black</a>
<a href='#3'>yellow</a>
<a href='#4'>pink</a>
<div id='1' style='width:500;height:200;background-color:red'> </div>
<div id='2' style='width:500;height:200;background-color:black'> </div>
<div id='3' style='width:500;height:200;background-color:yellow'> </div>
<div id='4' style='width:500;height:1200;background-color:pink'> </div>

  保存為html文件,然後自己點點超鏈接。沒錯,錨點就是為了能讓文檔滾動到指定的位置,而這個位置由你來定!因為是“滾動”,所以得有滾動條才行,如果木有滾動條那麼不能滾也就不能動了,錨點也就沒用了,仔細想想確實如此。錨點應用很廣,舉個大家都見過的例子,百度百科,裡面的導航使用的就是錨點技術。

  我們查看下它的實現代碼,實現也非常的easy

  錨點設置是個a標簽,它的href指向內容和跳轉位置的name值一致(其實差個#),需要注意的是如果用的是name,那麼必須用a標簽包裹,而該法在html5中已經被廢除。我們設置錨點通常采用id的方式,更簡單,也不會產生沒用的文檔元素。

  說完錨點,我們來說說location.hash。還是在博客園的百科頁面,在導航欄點擊”網站簡介“後,注意這時候地址欄發生了變化!多出來的的正是location.hash值(字符串)。

  而location.hash和location.href一樣,既能獲取它的值,也能用它進行重定向(重定位)。繼續留在博客園的百科主頁,然後在控制台輸入location.hash = "#2”,然後頁面就跳轉到”發展歷程“這部分了,和普通的錨點一樣的效果。

  而這個過程頁面是不會進行刷新的,但是如果要回到之前的頁面卻能使用浏覽器的前進、後退鍵。

如何跨域

  了解了這些基礎知識後,我們就要開始跨域了!

  其實很簡單,如果index頁面要獲取遠端服務器的數據,動態插入一個iframe,將iframe的src屬性指向服務端地址。這時top window和包裹這個iframe的子窗口是不能通信的(同源策略),所以改變子窗口的路徑就行了,將數據當做改變後的路徑的hash值加在路徑上,然後就能通信了(和window.name跨域幾乎相同),將數據加在index頁面地址的hash值上。index頁面監聽地址的hash值變化(html5有hashchange事件,用setInterval不斷輪詢判斷兼容ie6/7),然後做出判斷,處理數據。

<body>
  <script type="text/javascript">
    function getData(url, fn) {
      var iframe = document.createElement('iframe');
      iframe.style.display = 'none';
      iframe.src = url;

      iframe.onload = function() {
        fn(iframe.contentWindow.location.hash.substring(1));
        window.location.hash = '';
        document.body.removeChild(iframe);
      };

      document.body.appendChild(iframe);
    }

    // get data from server
    var url = 'http://localhost:8080/data.php';
    getData(url, function(data) {
      var jsondata = JSON.parse(data);
      console.log(jsondata.name + ' ' + jsondata.age);
    });
  </script>
</body>
   
<?php
  // 如果有必要則進行數據處理 $_GET['..']
  // code
  
  // 返回的數據
  $data = '{\"name\":\"hanzichi\",\"age\":10}';

  echo 
  "
  <script>
    window.location = 'http://localhost:81/location-hash/proxy.html' + '#' + \"$data\";
  </script>
  "
?>

  服務端文件中重定向的地址和index頁面需同源,這是通信的關鍵。

  然後在網上找了些別人寫的博客,基本都是加個第三方代理文件,原理是一樣的,服務端部分新建個iframe,然後將數據附加在location.hash上傳遞,也就是再嵌套個窗口,使之與祖輩窗口通信,個人認為更復雜了,有興趣的可以試試。

總結

  location.hash+iframe法和jsonp以及window.name+iframe一樣,都是雙向的,但是都只能是GET形式,所以數據只能加在url上。

  其實window.name和location.hash是異曲同工的,都是用了window下的屬性,畢竟location.hash也是window下的(window.location.hash)。

Copyright © Linux教程網 All Rights Reserved