一、什么是跨域?
一般来说,向一个非同源网站发送请求获取数据,就是跨域请求。
//跨域错误提示
Failed to load http://luna.58.com/api/getcity: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342'; is therefore not allowed access.

同源策略——跨域问题产生原因
浏览器为了网络信息安全所采取的的措施,限制资源访问权限。
来源相同是指:协议、主机(域名),端口号,全部相同。
http://www.example.com/dir/page.html
协议:http
域名:www.example.com
端口:80(默认端口,可以省略)
  • http://www.example.com/dir2/other.html:同源
  • http://example.com/dir/other.html:不同源(域名不同)(域名必须完全相同)
  • http://www.example.com:81/dir/other.html:不同源(端口不同)
域名级别
一级域名(顶级域名):baidu.com
二级域名:www.baidu.com
三级域名:wangshangyingxiao.club.1688.com

同源策略限制范围
//如果非同源,共有三种行为受到限制
(1)cookie、localstorage、IndexDB 无法读取
(2)DOM结构无法获得
(3)AJAX请求不能发送

二、跨域通信方法
1、设置document.domain
此方法只适用于:两个网页一级域名相同,二级域名不同(或者三级域名不同)
(1)共享cookie;(2)iframe窗口,获取dom结构。
实现方法:两个网页设置相同的document.domain,设置为一级域名,即可共享cookie
情景1:实现cookie共享,两个网页一级域名相同,二级域名不同。
cookie是服务器写入浏览器的信息,只有同源的网页才可以共享。
//举例说明:
A网页:http://w1.example.com/a.html 默认 document.domain 值为 w1.example.com
B网页:http://w2.example.com/b.html默认 document.domain 值为 w2.example.com
//设置相同的domain
document.domain = 'example.com';
//设置后
docoment.domain //两个页面的值均为 example.com
//A页面,设置cookie
document.cookie = 'test=hello';
//B页面,获取cookie
document.cookie //cookie的值中包含设置的test=hell

服务器也可以在设置cookie时,指定cookie的所属域名为一级域名, 这样的话,二级域名和三级域名不用做任何设置,都可以读取到这个cookie。
情景2:获取iframe的Dom结构,两个网页一级域名相同,二级域名不同。
iframe Dom结构:只有同源的页面才可以相互通信,获取DOM结构。
//举例说明:
父窗口:http://w1.example.com/a.html 默认 document.domain 值为 w1.example.com
子窗口iframe(#myIframe)http://w2.example.com/b.html默认 document.domain 值为w2.example.com
//设置前,非同源页面,父窗口获取子窗口dom,报错
document.getElementById('#myIframe').contentWindow.document
//Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.
//设置前,非同源页面,窗口获取父窗口dom,报错
window.parent.document.body
//Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.
//设置相同的domain
document.domain = 'example.com';
//设置后,即可获取Dom
docoment.domain //两个页面的值均为 example.com

2、片段识别符 (fragment identifier)
针对完全不同源的主页面与iframe页面,解决跨域通信的问题。将通信内容写入片段标识符中。
片段识别符是指URL中#号后面的部分,例如:http://example.com/x.html#fragment的#fragment。
只更改片段标识符,页面不会重新刷新。
缺点:片段标识符中数据长度受限
//父窗口将信息,写入子窗口的片段标识符
var iframeEle = document.getElementById('iframe');
console.log("父页面:" + location.href);
// console.log("父页面获取子页面url:" + iframeEle.contentWindow.location.href);//报错,跨域
/*片段标识符跨域*/
iframeEle.src = iframeEle.src + '#faterData';
window.onhashchange = function(){
console.log('父窗口hash变化:' + window.location.hash);
}

//子窗口监听hashchange事件得到通知
console.log("子页面:" + location.href);
// console.log("子页面获取父页面url:" + top.location.href);//报错,跨域
/*片段标识符跨域*/
window.onhashchange = function(){
console.log('子窗口hash变化:' + window.location.hash);
};
top.location.href = "http://localhost:63342/luna_gather/src/index_test.html#childData3";;
// top.location.href = top.location.href + "#childData2"; 报错,跨域

3.window.name
浏览器窗口有window.name属性,这个属性的特点是:只要在同一窗口中,无论是否同源,不同网页的window.name属性都是共享的。
优点:window.name数据容量大(相比片段识别符)
缺点:(1)必须同一窗口;(2)必须监听窗口window.name属性的变化,影响网页性能;
4.postMessage
可以实现完全不同源的窗口进行有限的通信。
语法:
(1)发送方发送消息
otherWindow.postMessage(message,targetOrigin,[transfer]);
①otherWindow:其他窗口的引用,如(1)iframeEle.contentWindow;(2)window.open返回的窗口对象;(3)命名过或数值索引的window.frames,如window.frames[0]
②message:传送数据
③targetOrigin:指定接受数据的窗口的源,可以为特定url,或者“*”,表示全部窗口
④transfer:是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送方将不再保留所有权。
(2)接收方,监听message事件,接收消息
window.addEventListener('message',function(event){});
messageEvent涉及到以下四个属性:
①type:message的类型
②data:postMessage发送过来的数据
③origin:调用postMessage方法的窗口的源,即发送消息的窗口的源
④source:调用postMessage方法的窗口对象
(3)案例演示
父页面:http://a.com/main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<iframe id="iframe" src="http://b.com/iframe.html" frameborder="0"></iframe>
</body>
<script type="text/javascript">
window.onload = function(){
var iframeEle = document.getElementById('iframe');
console.log("父页面:" + location.href);
// console.log("父页面获取子页面url:" + iframeEle.contentWindow.location.href);//报错,跨域
/*postMessage跨域*/
window.frames[0].postMessage("我是父页面", '*');//第一种方式
iframeEle.contentWindow.postMessage("我是父页面2", 'http://b.com/';);//第二种方式
window.addEventListener('message',function(e){
console.log("父窗口接受数据:" + e.data);
});
}
</script>
</html>

子页面:http://b.com/iframe.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<iframe id="iframe" src="http://b.com/iframe.html"; frameborder="0">
</iframe>
</body>
<script type="text/javascript">
window.onload = function(){
console.log("子页面:" + location.href);
// console.log("子页面获取父页面url:" + top.location.href);//报错,跨域
/*postMessage跨域*/
top.postMessage('我是子页面','http://a.com/main.html');
window.addEventListener('message',function(e){
console.log('子窗口接受数据:' + e.data);
e.source.postMessage('我接受到数据了','*');
},false);
}
</script>
</html>

注意:postMessage一定要在页面完成加载之后执行(即onload之后),否则会报错:
Failed to execute ‘postMessage’ on ‘DOMWindow’
可以利用postMessage,实现跨域窗口的localstorage操作。
 
5、AJAX
同源政策限制,AJAX请求只能发给同源网址,否则跨域报错。
除了架设服务器代理外,(即浏览器请求同源服务器,再由后者请求外部服务器),有三种方法规避同源限制
1、JSONP
2、WebSocket
3、CORS

具体内容,之后单独列出。

转载于:https://www.cnblogs.com/zuozuo-blog/p/9391230.html

跨域通信——多窗口通信相关推荐

  1. 关于父窗口获取跨域iframe子窗口中的元素

    这几天在项目中遇到,一个难点, 就是需要异步加载一个pdf插件, 同时又需要获取这个插件中的点击事件来生成用户的下载记录. 刚开始也是想了很多方法,网上搜的 格式1:$("#iframe的I ...

  2. js如何将跨域打开的窗口放到最前面_程序员的强迫症-便捷打开常用网站

    根据上一篇 程序员的强迫症–如何让电脑桌面变得非常干净?可以让电脑桌面非常简洁.干净,win + r 快速打开应用程序.常用文件夹. 这篇就介绍 win + r 便捷打开常用网站,优化管理 我们在日常 ...

  3. Iframe中跨域进行父子窗口进行通信的四种方法

    一.跨域简介 1. 首先简单介绍一下什么是跨域 当我们在浏览器的地址栏中输入一个地址的时候,这个地址通常包含四部分信息内容.这四部分信息包含:①协议.②域名.③端口.④资源位置. 其中前三部分将会决定 ...

  4. javascript同源策略和跨域实验及其跨域解决办法

    一.问题提出: 从应用A跳转到应用B,用户在应用B上操作完毕后,关闭页面,是否可以用程序自动刷新应用A窗口,以让用户观察操作效果.如支付宝充值,跳转到各银行界面进行充值,充值完毕后,支付宝页面相关自动 ...

  5. 跨域与jsonp及cors解决

    1. 什么是跨域? 跨域一词从字面意思看,就是跨域名嘛,但实际上跨域的范围绝对不止那么狭隘.具体概念如下:只要协议.域名.端口有任何一个不同,都被当作是不同的域.之所以会产生跨域这个问题呢,其实也很容 ...

  6. CORS解决跨域的几种实现方式

    目录 一.什么是跨域 二.同源策略 非同源限制 三.跨域的解决办法 CORS 3.1.两种请求 3.1.1.简单请求 3.1.2.非简单请求 3.2.CORS常用解决跨域的方法 3.2.1.HttpS ...

  7. 跨域问题详解——九种解决跨域方法

    跨域是前端再常见不过的问题了,下面主要针对跨域做一次总结,一次理清楚. 一.jsonp解决跨域 jsonp解决跨域问题的原理是:script不受同源策略的影响. //前端代码: <!DOCTYP ...

  8. 浅谈postMessage跨域通信与localStorage实现跨域共享

    我们可能有需要在多个域名之间共用同一个localStorage的需要 一.我们先测试不同域名之间的通信 1.有 child.html 如下,代码中 window.parent.postMessage( ...

  9. 【JavaScript】父子页面之间跨域通信的方法

    由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇"跨域,不再纠结&quo ...

  10. 前端跨域通信的几种方式

    前言 前端通信类的问题,主要包括以下内容: 1.什么是同源策略及限制 同源策略是一个概念,就一句话.有什么限制,就三句话.能说出来即可. 2.前后端如何通信 如果你不准备,估计也就只能说出ajax. ...

最新文章

  1. 吴 恩 达 教 你 做 机 器 学 习 职 业 规 划
  2. 敏捷开发一千零一问系列之四:优先级排错怎么办?
  3. 火焰效果材质实现_「游戏开发」使用Unity实现魔法火焰效果
  4. C#反射技术在多语言实现中的实际用处参考,让初学者学技术有个针对性【附源码】...
  5. python 读取excel太慢_Python 读取excel并转换为字典
  6. 还不会动效?优秀的可临摹素材,给你做个示范
  7. 灵玖软件:九眼智能文档核查云平台上线了
  8. 利用cli.go来写命令行应用
  9. K8s:调用Java接口创建容器
  10. gogs仓库代码拉取不需要用户账号验证问题
  11. java查询F分布表
  12. 软件测试——测试流程重要性
  13. NFT+体育,卡塔尔世界杯有哪些NFT看点!
  14. 谷歌大脑创始成员辞职,他也和Jeff Dean闹掰了
  15. 运放TL08系列,功放LM386,8欧姆的扬声器
  16. rar压缩包找回压缩密码
  17. 从程序员到项目经理:懂电脑更要懂人脑
  18. 老男孩linux培训-python三期下载
  19. python wifi模块
  20. android-检测耳机的插入和拔出动作

热门文章

  1. Cocos2d-x-使用脚本概述
  2. 游戏开发之.h、.c、.hpp及.cpp的区别
  3. Find命令使用详解及实例分析
  4. JAVA当中数组学习(初级)
  5. 【模板】字符串hash
  6. DNS域名解析基础知识
  7. 这家保险公司的第三朵云为什么选择Power?
  8. STL—内存的配置与释放
  9. 《TensorFlow技术解析与实战》——1.1 什么是人工智能
  10. Apache Spark源码走读(十)ShuffleMapTask计算结果的保存与读取 WEB UI和Metrics初始化及数据更新过程分析...