前言

  如果看懂了前文利用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上传递,也就是再嵌套个窗口,使之与祖辈窗口通信,可以参考js中各种跨域问题实战小结(二) - 大额_skylar,个人认为更复杂了,有兴趣的可以试试。

总结

  location.hash+iframe法和jsonp以及window.name+iframe一样,都是双向的,但是都只能是GET形式,所以数据只能加在url上。

  其实window.name和location.hash是异曲同工的,都是用了window下的属性,毕竟location.hash也是window下的(window.location.hash)。

参考

  1. URL的井号
  2. 锚点跳转及jquery下相关操作与插件
  3. js中各种跨域问题实战小结(二) - 大额_skylar

利用location.hash+iframe跨域获取数据详解的更多相关文章

  1. 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  2. iframe 跨域问题解决方案 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  3. javascript跨域通信(一):利用location.hash实现跨域iframe自适应

    页面域关系: a.html所属域A:www.A.comb.html所属域B:www.B.com 问题本质: js对跨域iframe访问问题,因为要控制a.html中iframe的高度和宽度就必须首先读 ...

  4. 利用window.name+iframe跨域获取接口数据

    最近做了一个表单广告,需要从接口读取数据,做完发现谷歌火狐下正常,360兼容和IE浏览器无法获取数据,以下是鲜明的对比:      调试发现报错了: 然后开发把接口改成支持windowname,一开始 ...

  5. jQuery之ajax的跨域获取数据

    如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型.使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面.服务 ...

  6. XMLHTTPRequest对象不能跨域获取数据?!

    写了一小段代码,是用XMLHTTPRequest对象来获取数据的,在本地服务器中,运行的很顺利,但是转向实际服务器(实质上就是转向http://gumball.wickedlysmart.com获取一 ...

  7. jsonp跨域获取数据小解

    jsonp跨域获取数据小解 由于浏览器有同源策略,所以要想获取非同源(协议,域名,端口三者有一不同都算非同源)的页面的数据,就得进行跨域 (1) jsonp原理 由于script标签的src属性可以访 ...

  8. js中几种实用的跨域方法原理详解(转)

    今天研究js跨域问题的时候发现一篇好博,非常详细地讲解了js几种跨域方法的原理,特分享一下. 原博地址:http://www.cnblogs.com/2050/p/3191744.html 下面正文开 ...

  9. js中几种实用的跨域方法原理详解

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

随机推荐

  1. 《数据结构与算法JavaScript描述》

    <数据结构与算法JavaScript描述> 基本信息 作者: (美)Michael McMillan 译者: 王群锋 杜欢 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9 ...

  2. 使用culr

    使用curl在采集有语言要求的网站时,首先需要发送带有语言设置的请求,再发送你要的请求如: 注:vget(); 这里没提供: $url='http://www.hotels.com/?locale=e ...

  3. cocos2d-x之action初试

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...

  4. poj 2195 KM算法

    题目链接:http://poj.org/problem?id=2195 KM算法模板~ 代码如下: #include "stdio.h" #include "string ...

  5. SQLAlchemy 中文文档翻译计划

    SQLAlchemy 中文文档翻译计划已启动. Python 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质.交流群:467338606. 希望大家能够勇敢地去翻译和改进翻译.虽然我 ...

  6. linux64位android项目R文件无法生成以及Cannot run program adb

    1.本机kali2.0  64位,kali基于Debian. 2.android adb是32位,64位linux要安装32位依赖库,注意ia32-lib被lib32z1替代. 3.执行命令 sudo ...

  7. Linux ethtool命令

    一.简介 ethtool 是用于查询及设置网卡参数的命令. 二.常用选项 ethtool ethx //查询ethx网口基本设置,其中 x 是对应网卡的编号,如eth0.eth1等等 ethtool ...

  8. Best Time to Buy and Sell Stock II

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  9. WCF MSMQ消息队列与离线操作

    消息队列类型 公共队列:整个网络中的节点都可以访问到 专用队列:本地计算机,知道路径者可以访问 管理队列:包含确认在给定“消息队列”网络中的发送的消息回执的消息 相应队列:返回给发送程序的相应信息

  10. 【转载】jQuery Validate验证框架 + CKEditor 无法验证问题的解决方法

    文章1:http://yangzhihuan.iteye.com/blog/717254 CKEDITOR.instances["page_content"].on("i ...