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. 确定比赛名次---hdu1285(拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 拓扑序就是求一个序列 数 a 出现在数 b 前面,最终输出满足条件的序列即可: 过程就是每次选取 ...

  2. SSL延迟有多大?(转)

    add by zhj: SSL层在TCP层之上,SSL握手是在TCP握手完成之后,除了这点之外,两者应该是相对独立的过程.在服务端,这两个过程有可能不在同一台主机上, 比如服务端用LVS+Nginx实 ...

  3. SpringBoot安装和创建简单的Web应用

    SpringBoot安装 方式一: Eclipese->Help->Eclipse Marketplace ->Finde STS -> Install 注意:安装过程中挺慢, ...

  4. (0.2.6)Mysql安装——编译安装

    (0.2.6)Mysql安装——编译安装 待完善

  5. 数据分析之可反复与独立样本的T-Test分析

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jia20003/article/details/24201297 数据分析之独立样本的T-Test分 ...

  6. Spark2.0机器学习系列之4:Logistic回归及Binary分类(二分问题)结果评估

    参数设置 α: 梯度上升算法迭代时候权重更新公式中包含 α :  http://blog.csdn.net/lu597203933/article/details/38468303 为了更好理解 α和 ...

  7. XE6移动开发环境搭建之IOS篇(2):安装虚拟机(有图有真相)

    XE6移动开发环境搭建之IOS篇(2):安装虚拟机(有图有真相) 2014-08-15 22:04 网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的内容.傻瓜式的表 ...

  8. vue 项目中assets文件夹与static文件夹引用的区别

    首先,assets文件夹和static文件夹在vue-cli生成的项目中,都是用来存放静态资源的. 1.assets目录中的文件会被webpack处理解析为模块依赖,只支持相对路径形式.build的时 ...

  9. 关于js中的取值问题

    像这样是获取不到值的,弹出的消息是 underfined:<html><style type="text/css">input { border: 1px ...

  10. kafka的javaapi生产者生产消息,消费者获取不到

    zookeeper和kafka的日志没有出现什么报错 linux下kafka的命令行能生产并收到消费消息 但是在idea(windows环境下)中,调用api,获取不到数据,也生产不了数据,现象就是没 ...