js跨域问题是指在js在不同的域中进行数据传输或者数据通信,比如通过ajax向不同的域请求数据(说到ajax,不可避免的就会遇到两个问题:一是ajax是如何传递数据的?二是ajax是如何实现跨域的?),或者是js获取在页面内的不同域的框架中的数据(iframe),ifame在不同域下的js通信。

跨域的表现主要有:协议不同,主机名不同,端口号不同

比如

http://www.abc.com和https://www.abc.com属于协议不同

http://www.abc.com和http://qqq.abc.com属于主机名不同

http://www.abc.com和http://www.abc.com:80属于端口号不同

而http://www.abc.com和http://www.abc.com/list.html是属于同域下的

第一种解决跨域问题的方法是:通过jsonp

在js中,我们直接通过XMLHttpRequest请求不同域的数据是不可以的,jsonp通过引入js脚本的方式解决了这个问题,比如假设需要在a.html中通过ajax获取不同域上的json数据,假设这个json数据就在http://www.abc.com/data.php,那么可以通过以js文件的形式引入

a.html

<script>

function dosomething(jsondata) {

//这里处理获得的json数据

}

</script>

<script src="http://www.abc.com/data.php?callback=dosomething"></script>

这里的获取数据的地址后还有callback参数是惯用参数名,因为是当做js文件引入的,那么返回的也应该是js文件,所以在这个页面的php中应该是这样的

<?php

  $callback = $_GET('callback');//得到回调函数名

  $data = array('a','b','c');//传递的数据

  echo $callback.'('.json_encode($data).')';//输出

?>

输出:dosomething(['a','b','c'])

因此我们可以很清楚地知道,dosomething函数就是通过http://www.abc.com/data.php?callback=dosomething返回的js文件,dosomething函数的参数是返回的json数据,这样我们就得到了跨域的数据

所以通过jsonp的方法解决跨域问题的思路是,通过script标签引入一个js文件,这个js文件载入成功后会执行url参数中指定的函数,并且会把获取的json数据当做参数传入,所以jsonp是需要服务器端页面的配合的。

jQuery可以很方便地封装jsonp

<script>

 $.getJSON("http://www.abc.com/data.php?callback=?",function(){

  //处理JSON数据

});

</script>

jquery会自动生成一个全局函数来代替callback=?的?,与js实现的原理是一致的,之后获取到数据后,全局函数又会自动销毁,相当于一个临时代理函数的功能,

$getJSON方法可以自动判断是否跨域,如果不跨域,则按普通的ajax方法,如果跨域,就通过异步加载调用js文件来调用jsonp的回调函数。

二、document.domain

这个方法说到底就是将两个域设置成相同的域名,比如,可以把http://www.a.com和http://a.com设成相同的域名即可,但是这个设置是有条件限制的,document.domain只能设置成自身或更高一级的父域,比如b.c.a.com可以设成、b.c.a.com、c.a.com、a.com都是可以的,但是设成d.b.c.a.com是不可以的,因为这是b.c.a.com的子域,同样,设成d.com也是不可以的,因为已经是不同域了。

而且document.domain只适用于不同的子域之间的框架间的交互,如果要通过ajax方法进行跨域获取数据的话,可以在本页面设置一个隐藏的iframe来进行代理,将ifame载入跟需要获取数据的那个页面相同的域的页面,然后通过iframe获取数据,而js也可以正常的操作这个iframe,再通过document.domain方法去获取iframe里的数据就可以了。

举个例子:

在http://a.html里设置主域,

<script>

  document.domain="a.html";//设置成主域

  function test(){

    alert("document.getElementById('iframe').contentWindow");

  }

</script>

<body>

//载入需要获取页面的数据

  <iframe id="iframe" src="http://b.com/data.html" onload="test()" ></iframe>

</body>

最新文章

  1. maven内部运行原理解析
  2. 文档对象模型(DOM)中的结点属性
  3. NSIS打包(二)第一个安装包
  4. ubuntu自带的gedit编辑器添加Markdown预览插件
  5. txt 分割程序
  6. 阿里云Linux服务器挂载硬盘分区
  7. 默认权限umask、文件系统权限、特殊权限
  8. 单KEY业务,数据库水平切分架构实践
  9. C++11智能指针的深度理解
  10. 成功使Linux服务端和Windows客户端建立socket通信
  11. vb.net 變量及数据类型
  12. MT【9】绝对值二次函数
  13. python字符串前带u,r,b的含义
  14. Linux学习: LCD驱动
  15. vijos 1098 合唱队形 - 动态规划
  16. 关于HSQLDB访问已有数据库文件的操作说明
  17. C# 在RichTextBox根据内容自动调整高度
  18. 中南月赛F ZZY and his little friends
  19. 正则基础之——NFA引擎匹配原理
  20. AS3.0纯代码编写的两款loading效果

热门文章

  1. Spring RESTful + Redis全注解实现恶意登录保护机制
  2. Android实现录屏直播(三)MediaProjection + VirtualDisplay + librtmp + MediaCodec实现视频编码并推流到rtmp服务器
  3. 2272: [Usaco2011 Feb]Cowlphabet 奶牛文字
  4. 1625: [Usaco2007 Dec]宝石手镯
  5. android 透明状态栏方法及其适配键盘上推(一)
  6. 如何javascript获取css中的样式
  7. javascript继承---组合式继承
  8. cuda编程学习3——VectorSum
  9. pcntl_fork 导致 MySQL server has gone away 解决方案
  10. java学习笔记 --- String类