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 入门

    1. 入门概述 SpringBoot专注于快速方便的开发单个个体微服务; SpringCloud:关注全局的微服务协调治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来, 为各个微 ...

  2. UDP和TCP的主要特点

    UDP的主要特点是:(1)无连接:(2)尽最大努力交付:(3)面向报文:(4)无拥塞控制:(5)支持一对一.一对多.多对一和多对多的交互通信:(6)首部开销小(只有四个字段:源端口.目的端口.长度.检 ...

  3. 剑指Offer——二叉树的下一个结点

    题目描述: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 如果该结点存在右子树,那么返回右子树的最左结 ...

  4. d3.js 之增加感染力:使用转场效果

    转场/transition 图形比数据有感染力,动起来的图形比静态的图形更有感染力. 转场是一种过渡,提供两个稳定状态间的一种动态渐进的变化.转场的概念来源于电影. 电影中存在不同场景之间的切换,比如 ...

  5. 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活--hdu2191(多重背包模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 标准的多重背包 题目 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是 ...

  6. 2018 又一个假期 over 了

    五一假期三天  在家窝三天  早上起床仍感觉没休息好  其实确实没休息好  假期的时间总不愿意拿来补觉用.周末准备去体检,真心恐惧医院的味道,硬着头皮还得上啊.

  7. Android中TextView设置最大长度,超出显示省略号

    今天在项目中碰到一个问题,在一个页面的顶部的标题栏显示公司的名字,但由于公司名称较长,显示不开,影响美观.故在网上查阅资料,在此做个小的总结. TextView中有个ellipsize属性,作用是当文 ...

  8. 关于DOM事件操作

    事件的三要素: 事件源.事件.事件驱动程序. 事件源.: 引发后续事件的html标签   document.getElementById(“box”) document.getElementsByCl ...

  9. 把typora改为微软雅黑+Consolas

    前言 typora是一款非常方便的书写markdown文本的编辑器.官网:https://www.typora.io/ 对于字体强迫症患者来说,不把字体改成微软雅黑+Consolas,那是相当难受.本 ...

  10. 核心动画(CAKeyframeAnimation,CABasicAnimation)

    一,核心动画常用的三种例子 view的核心动画其体现就是把view按照指定好的路径进行运动,针对的是view的整体. [view.layer addAnimation:动画路径 forKey:@“绑定 ...