JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。因为同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。

下表给出了相对 http://site.baidu.com/file/index.html 同源检测的示例:

序号  URL 结果 原因
http://site.baidu.com/file/inner/1.html 成功 同一域名
2 http://site.baidu.com/file2/2.html 成功 同一域名不同文件夹
3 https://site.baidu.com/secure.html 失败 不同协议 ( https )
4 http://site.baidu.com:81/file/etc.html 失败 不同端口 ( 81 )
5 http://wiki.baidu.com/file/other.html 失败 不同主机 ( wike)

1、主域相同的跨域

主域相同的跨域

document.domain的场景只适用于不同子域的框架间的交互,及主域必须相同的不同源。

页面可能会更改其自己的来源,但有一些限制。脚本可以将 document.domain的值设置为其当前域或其当前域的超级域。如果将其设置为其当前域的超级域,则较短的域将用于后续原始检查。例如,假设文档中的一个脚本在 http://site.baidu.com/file/2.html 执行以下语句:

 document.domain = "baidu.com";

这条语句执行之后,页面将会成功地通过对 http://baidu.com/file/index.html 的同源检测。

//www.a.com上的a.html

document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
// 在这里操纵b.html
alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
}; //script.a.com上的b.html document.domain = 'a.com';

注:

1. 某一页面的domain默认等于window.location.hostname。

2. 主域名是不带www的域名,例如a.com,主域名前面带前缀的通常都为二级域名或多级域名,例如www.a.com其实是二级域名。

3. domain只能设置为主域名,不可以在b.a.com中将domain设置为c.a.com。

4. 使用document.domain允许子域安全访问其父域时,需要设置document域在父域和子域中具有相同的值。这是必要的,即使这样做只是将父域设置回其原始值。否则可能会导致权限错误。这里都是a.com。

2. 动态创建script

虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。具体的做法可以参考YUI的Get Utility

这里判断script节点加载完毕还是蛮有意思的:ie只能通过script的readystatechange属性,其它浏览器是script的load事件。以下是部分判断script加载完毕的方法。

js.onload = js.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
// callback在此处执行
js.onload = js.onreadystatechange = null;
}
};

优点:简单适用,老式浏览器全部支持,服务器改造小。不需要XMLHttpRequest或ActiveX的支持。
 缺点:只支持GET请求。

3. 使用HTML5 postMessage

HTML5中最酷的新功能之一就是 跨文档消息传输Cross Document Messaging。下一代浏览器都将支持这个功能:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。 Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递。

各浏览器兼容性如下:

一个简单的例子:

var popup = window.open('http://bbb.com', 'title');//父窗口http://aaa.com向子窗口http://bbb.com发消息,调用postMessage方法。
popup.postMessage('Hello World!', 'http://bbb.com');

postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送。

父窗口和子窗口都可以通过message事件,监听对方的消息。message事件的事件对象event,提供以下三个属性:

  • 1、event.source:发送消息的窗口。
  • 2、event.origin: 消息发向的网址。
  • 3、event.data:消息内容。
 var onmessage = function (event) {
var data = event.data;//消息
var origin = event.origin;//消息来源地址
var source = event.source;//源Window对象
if(origin == "http://www.aaa.com"){
console.log(data);//hello world!
}
source.postMessage('Nice to see you!', '*');
};
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', onmessage, false);
} else if (typeof window.attachEvent != 'undefined') {
//ie
window.attachEvent('onmessage', onmessage);
}

4. 通过CORS跨域

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。所有浏览器都支持该功能,IE浏览器不能低于IE10

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

具体信息可以看下这篇博客:http://www.ruanyifeng.com/blog/2016/04/cors.html

javascript 跨域访问的更多相关文章

  1. 利用javascript跨域访问cookie之广告推广

    在上一篇<说一说javascript跨域和jsonp>中,利用JSONP进行了跨域的数据访问,利用JS本身的跨域能力在远端生成HTML结构的方式完成了一个小广告. 在实际应用中, 跨域使用 ...

  2. Javascript 跨域访问解决方案 总结

    在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义.同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问 ...

  3. 三种方法实现js跨域访问

    转自:http://narutolby.iteye.com/blog/1464436 javascript跨域访问是web开发者经常遇到的问题,什么是跨域,一个域上加载的脚本获取或操作另一个域上的文档 ...

  4. 【JavaScript】frame跨域访问元素

    什么是跨frame访问元素呢?比如main.html中有如下代码: <frameset cols="50%,*"> <frame src="frame1 ...

  5. 解决cookie跨域访问

    一.前言 随着项目模块越来越多,很多模块现在都是独立部署.模块之间的交流有时可能会通过cookie来完成.比如说门户和应用,分别部署在不同的机器或者web容器中,假如用户登陆之后会在浏览器客户端写入c ...

  6. JavaScript 跨域漫游

    前言: 最近在公司做了几个项目都涉及到了iframe,也就是在这些iframe多次嵌套的项目中,我发现之前对iframe的认识还是比较不足的,所以就静下心来,好好整理总结了iframe的相关知识:&l ...

  7. Angular2中对ASP.NET MVC跨域访问

    应用场景 项目开发决定使用angular2进行前后端分离开发,由我负责后端服务的开发,起初选择的是web api进行开发.对跨域访问通过API中间件+过滤器对跨域访问进行支持.开发一段后,通知需要移植 ...

  8. cookie 跨域访问的解决方案

    Cookie 同域单点登录  最近在做一个单点登录的系统整合项目,之前我们使用控件实现单点登录(以后可以介绍一下).但现在为了满足客户需求,在不使用控件情况下实现单点登录,先来介绍一下单点登录.    ...

  9. Jsonp跨域访问

    很早之前看过好几篇跨域访问的文章,然后做项目的时候基本没有遇到跨域访问的问题.不过该来的还是会来,前些天终于让我遇到了.于是重温了一下原理这些,再进行实战.于是现在也敢通过实战后的一些理解来和大家分享 ...

随机推荐

  1. SpringCloud 进阶之Ribbon和Feign(负载均衡)

    1. Ribbon 负载均衡 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端,负载均衡的工具; 1.1 Ribbon 配置初步 1.1.1 修改 micros ...

  2. react es6语法 之 => 箭头函数

    参考:https://www.cnblogs.com/secretAngel/p/9699356.html (1).只有一个参数且只有一句表达式语句的,函数表达式的花括号可以不写let test = ...

  3. Apache Lucene初探

    讲解之前,先来分享一些资料 首先,学习任何一门新的亦或是旧的开源技术,百度其中一二是最简单的办法,先了解其中的大概,思想等等.这里就贡献一个讲解很到位的ppt 这是Lucene4.0的官网文档:htt ...

  4. tomcat查看GC信息

    tomcat启动参数,将JVM GC信息写入tomcat_gc.log CATALINA_OPTS='-Xms512m -Xmx4096m -XX:PermSize=64M -XX:MaxNewSiz ...

  5. SyntaxError: Missing parentheses in call to 'print'. Did you mean print('XXXXXX')?

    因为Python3中取消了以前Python 2中的语法. 所以Python 3再使用python2的语法格式就会报错 错误信息中提示需要加上括号,字符串可以用单引号或双引号括起来 这样就不会报错了.

  6. 006-Hadoop Hive sql语法详解1-数据结构和Hive表建立

    1.认识hive:  Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构化的数据文件映射为一张数据库表, ...

  7. python学习笔记(二十)初识面向对象

    面向对象的编程的主要思想是把构成问题的各个事物分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述一个事物在解决问题的过程中经历的步骤和行为.对象作为程序的基本单位,将程序和数据封装其中, ...

  8. 推荐系统第4周--- 基于频繁模式的推荐系统和关联规则挖掘Apriori算法

    数据挖掘:关联规则挖掘

  9. iis7.5安装配置php环境详细清晰教程,三步实现【图文】

    iis7.5安装配置php环境详细清晰教程,三步实现[图文] iis7.5是安装在win7.win8里的web服务器,win2003.win2000的web服务器使用的是iis6.0,由于win7.w ...

  10. debian7更换gcc版本的二种方法分享

    debian7更换gcc版本的二种方法分享   最近在编译qt,之前用的是debian6,gcc版本是gcc-4.4,当使用debian7时,编译遇到了很多跟debian6不一样的问题,debian7 ...