Html5 postMessage实现跨域消息传递
一、同源策略
要理解跨域,我们首先要知道什么是同源策略。百度百科上这样定义同源策略:同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
何谓同源:如果两个URL的域名、协议、端口相同,则表示他们同源。
浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。 (白帽子讲web安全[1])。根据这个策略,a.com域名下的JavaScript无法跨域操作b.com域名下的对象。比如,baidu.com域名下的页面中包含的JavaScript代码,不能访问google.com域名下的页面内容。
JavaScript必须严格遵循浏览器的同源策略,包括Ajax(事实上,Ajax也是由JavaScript组成)。通过XMLHttpRequest对象实现的Ajax请求,不能向不同的域提交,比如,在abc.test.com下的页面,不能向def.test.com提交Ajax请求。运用了同源策略之后,用户就能确保自己正在查看的页面确实来自于正在浏览的域。
同源策略在现实应用中是十分重要的。假设攻击者利用Iframe把真正的银行登录页面嵌到他的页面上,当用户使用真实的用户名、密码登录时,该页面就可以通过JavaScript读取到用户表单中的内容,这样用户名和密码信息就被泄漏了。
在浏览器中,<script>、<link>、<img>、<iframe>等标签都可以加载跨域资源,不受同源策略限制,但是通过src加载的资源,浏览器限制了javascript的权限,不能进行各种的读写。从而,即使请求发了,敏感数据回来了,也是取不到的。
二、postMessage实现跨域
语法:window.postMessage(msg,targetOrigin)
window: 指目标窗口,可能是window.frames属性的成员或者由window.open方法创建的窗口
message:要发送的消息,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果
targetOrigin:“目标域“,包括:协议、主机名、端口号。若指定为”*“,则表示可以传递给任意窗口,指定为”/“,则表示和当前窗口的同源窗口。
获取postMessage传来的消息:为页面添加onmessage事件
window.addEventListener('message',function(e) {
}
onmessage事件接受一个参数e,它是一个event对象。
e的几个重要属性:
1、data:postMessage传递过来的msg
2、发送消息的窗口对象
3、origin:发送消息窗口的源(协议+主机+端口号)
来写一个简单的demo:
http://source.com/source.html用来发送数据:
<iframe id="iframe" src="http://target.com/target.html"></iframe>
<input id="msg" type="text" placeholder="请输入要发送的消息">
<button id="send">发送</button>
window.onload =function() {
document.getElementById('send').onclick = function() {
var msg = document.getElementById('msg').value;
var iframeWindow = document.getElementById('iframe').contentWindow;
iframeWindow.postMessage(msg,"http://target.com/target.html");
}
}
http://target.com/target.html用来接收数据:
<div>
<h2>target.html,以下是接收到的消息:</h2>
<section id="msg"> </section>
</div>
window.onload = function() {
if(window.addEventListener){
window.addEventListener("message", handleMessage, false);
}
else{
window.attachEvent("onmessage", handleMessage);
}
function handleMessage(event) {
event = event || window.event;
if(event.origin === 'http://source.com') {
document.getElementById('msg').innerHTML = event.data;
}
}
}
运行结果如下:

点击发送按钮的时候,target.html将会受到发送的消息。
Html5 postMessage实现跨域消息传递的更多相关文章
- [转]html5: postMessage解决跨域和跨页面通信的问题
[转]html5: postMessage解决跨域和跨页面通信的问题 平时做web开发的时候关于消息传递,除了客户端与服务器传值,还有几个经常会遇到的问题: 多窗口之间消息传递(newWin = wi ...
- html5 postMessage解决跨域、跨窗口消息传递
一些麻烦事儿 平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题 1.页面和其打开的新窗口的数据传递 2.多窗口之间消息传递 3.页面与嵌套的iframe消息传递 4. ...
- html5 postMessage解决跨域、跨窗口消息传递[转载]
原文:http://www.cnblogs.com/dolphinX/p/3464056.html 一些麻烦事儿 平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题 1 ...
- html5 postMessage解决跨域、跨窗口消息传递(转)
仅做学习使用,原文链接:http://www.cnblogs.com/dolphinX/p/3464056.html 一些麻烦事儿 平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经 ...
- html5: postMessage解决跨域通信的问题
效果图 postmessage解析 HTML5提供了新型机制PostMessage实现安全的跨源通信. 语法 otherWindow.postMessage(message, targetOrigin ...
- 使用 html5 postMessage 实现跨域
英文原文 中文翻译 因为web的安全机制,浏览器的同源策略.在不同域之间做数据交换就会涉及到跨域.A域如果要实现向B域发关消息,多多少少要有对B域有一定控制权,最起码人家B域要接收你的消息啊. 最近发 ...
- 解决Iframe跨域高度自适应,利用window.postMessage()实现跨域消息传递页面高度(JavaScript)
在iframe跨域引用高度自适应这块写的js方式都试了不管用,最终使用的是window.postMessage() 跨域获取高度 传递信息 1.首先,在主页面上使用iframe引入子页面:也就是A.h ...
- window.postMessage()实现跨域消息传递
window.postMessage() 方法可以安全地实现跨源通信.通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https), 端口号(443为https的默认值), ...
- 利用html5 postMessage接口跨域设置iframe大小
<!doctype html> <html> <head> <title>Document A</title> <meta chars ...
随机推荐
- shiro自定义realm支持MD5算法认证(六)
1.1 散列算法 通常需要对密码 进行散列,常用的有md5.sha, 对md5密码,如果知道散列后的值可以通过穷举算法,得到md5密码对应的明文. 建议对md5进行散列时加salt(盐),进行 ...
- JS禁止鼠标右键、禁止全选、复制、粘贴的方法(所谓的防盗功能)
简述:一个防君子不防小人的鸡肋的功能,针对小白还行. 代码如下: <script> //都能支持 document.oncontextmenu = function (e) { retur ...
- 【转】OpenCV—imread读取数据为空
之前遇到一个很郁闷的问题,因为从用OpenCV2.3.1改成OpenCV2.4.4,开始改用Mat和imread来代替Iplimage和cvLoadImage,出了点小问题:imread读入数据总是为 ...
- quart源码阅读(一)
def run( self,host: str='127.0.0.1',port: int=5000,ssl: Optional[SSLContext]=None,debug: Optional[bo ...
- 012_如何清除DNS缓存
运维过程中经常会进行切换域名解析等的操作,就需要查看是否更新.但常常DNS设置已经更新了,但是用户那边的DNS还是没有更新. 以下分析几点原因及我的解决方案. 一. <1>本地你的dns缓 ...
- android手机访问app网页报错:net::ERR_PROXY_CONNECTION_FAILED
手机访问网页报错:net::ERR_PROXY_CONNECTION_FAILED 手机访问app中嵌入的html网页报错: net::ERR_PROXY_CONNECTION_FAILED 原来是手 ...
- zabbix系列(四)Zabbix3.0.4添加对Nginx服务的监控
Zabbix3.0.4添加对Nginx服务的监控 通过Nginx的http_stub_status_module模块提供的状态信息来监控,所以在Agent端需要配置Nginx状态获取的脚本,和添加ke ...
- 转载:gc的概念,如果A和B对象循环引用,是否可以被GC?
原文:https://www.cnblogs.com/zhchoutai/p/6784929.html ①首先说一下,GC里边在JVM其中是使用的ROOT算法,ROOT算法,什么称作为ROOT呢,就是 ...
- SKlearn库学习曲线
思想: # 1.现将所有样本用交叉验证方法或者(随机抽样方法) 得到 K对 训练集-验证集# 2.依次对K个训练集,拿出数量不断增加的子集如m个,并在这些K*m个子集上训练模型.# 3.依次在对应训练 ...
- JS定义一个立即执行的可重用函数
我定义了一个函数表达式 testFun var testFun = (function() { ... //函数内容})(); 测试结果:虽然 testFun 函数有如愿在页面加载后立即被执行,但再次 ...