HTML5跨文档通信
跨文本通信是HTML5的一个新的API,今天来讲讲跨文本通信的知识。
一、iframe
在统一域名下,不同窗口间的通信可以使用iframe。我们可以从一个页面操作iframe里面页面的DOM结构 通常我们在一个页面上可以引用iframe框架。使用JS也可以在页面上操作框架里面的内容
(1)我们在1.html页面中引入下段代码
这样就把2.html在1.html页面中呈现出来。
(2)操作iframe里面的DOM元素,首先获取iframe页面的window对象
获取iframe框架的window对象,需要在有服务器环境下,使用contentWindow方法。
(3)获取对象后就操作这个对象。
获取到iframe对象后,然后再依次获取到iframe的document,body对象,再获取到具体DOM元素。这样就可以修改一个iframe对象了 一个完整的跨文本通信的例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload=function(){
var oBtn=document.getElementById('btn')
var myFrame=document.getElementById('myframe')
oBtn.onclick=function(){
// alert(myFrame.contentWindow)//[object Window]
myFrame.contentWindow.document.body.style.background='red'
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="点击变化iframe背景颜色">
<div style="border: 1px solid #ccc;width:200px;height: 100px;">
<iframe src="2.html" frameborder="0" id="myframe" width="200" height="100"></iframe>
</div>
</body>
</html>
最后就可以改变这个2.html文件的背景颜色了。这就是在同一个域名下,跨文本通信。 在iframe下,可以通过子级来改变父级的DOM结构。比如说在2.html里面有个按钮,使用parent方法可以改变1.html的背景颜色 parent方法——如果当前页面是顶级页面,没有被其他页面包含,那么parent就是当前页面的window对象,如果被包含了,则parent就是包含当前页面的父级页面的window对象 在2.html里面放置一个按钮,通过parent改变1.html页面的背景颜色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload=function(){
var oBtn=document.getElementById('btn')
oBtn.onclick=function(){
parent.document.body.style.background='green'
}
}
</script>
</head>
<body>
这是2.html里面的内容
<input type="button" id='btn' value="改变1.html的背景颜色">
</body>
</html>
二、widnow.open方法
window.open()方法也可以实现跨文本通信 window.open()可以接受多个值,也可以接收弹出页面。window.open()返回被打开窗口的window对象。用一个变量将这个页面对象存起来,就可以操作这个打开的页面了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload=function(){
var oBtn=document.getElementById('btn')
var oBtn1=document.getElementById('btn1')
var Open=null;
oBtn.onclick=function(){
Open=window.open('2.html','_blank')
}
oBtn1.onclick=function(){
Open.document.body.style.background="red"
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="点击存储window.open">
<input type="button" id="btn1" value="点击变化window.open页面">
</body>
</html>
最后的结果就是点击第二个按钮,就改变了2.html页面的背景颜色。这就可以实现跨文本通信方法。 window.open()也可以通过子级改变父级的方法。要使用window.opener()方法,打开当前页面的window。上例中也就是在2.html里面使用widnow.opener改变1.html页面 以上是在统一域名下,改变不同页面之间的通信,如果是在不同域名下呢?那应该怎么实现跨域的通信问题呢?这里就要使用postMessage了
三、postMessage
当不在同一个域名下的时候,就会产生跨域的问题,通过postMessage方法可以给另外的窗口发送信息。 发送页面使用postMessage方法接收两个参数。第一个参数表示发送的信息或数据;第二个参数表示接收信息的域名(要带上http,https协议) 接收信息的页面使用message来触发接收到的信息。message表示当窗口接收到通过postMessage发送过来的数据的时候触发,message事件对象保存了发送过来的内容。 最后通过ev.data来表示发送过来的数据,ev.origin表示发送信息的域名。 postMessage()方法的几个重要事件属性: ev.source – 消息源,消息的发送窗口/iframe。 ev.origin – 消息源的URI(可能包含协议、域名和端口),用来验证数据源。 ev.data – 发送方发送给接收方的数据。 比如下面的例子:如果我们在1.html里面将iframe里面的2.html链接设置为绝对路径,与1.html并不在同一域名下,通过1.html是操作不了2.html的。存在跨域的问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload=function(){
var oBtn=document.getElementById('btn')
var myframe=document.getElementById('myframe')
oBtn.onclick=function(){
myframe.contentWindow.document.body.style.background='red'
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="改变2.html的背景颜色">
<iframe src="http://www.webforend.com/uploads/file/2.html" frameborder="0" width='200' height='200' id='myframe'></iframe>
</body>
</html>
上述的代码是操作不了2.html的,因为存在跨域的问题。所以我们使用postMessage方法,来操作2.html 将1.html页面的点击事件中的代码改为:
oBtn.onclick=function(){
myframe.contentWindow.postMessage('100','http://www.webforend.com/uploads/file')
}
100表示发送的数据,网址表示请求的网址。 那么在2.html页面中,我们使用massage接受1.html发送过来的数据。在1.html中就可以弹出这个发送的信息 2.html内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload=function(){
window.addEventListener('message',function(ev){
alert('接收到了1.html的信息'+ev.data)//得到1.html传过来的内容
if(ev.data=='123'){
document.body.style.background='red'
}
})
}
</script>
</head>
<body>
这是2.html里面的内容
</body>
</html>
最后的结果:
也就是说我在1.html页面中发送信息成功。并且使用ev.data得到了1.html传过来的信息。 我在2.html中对ev.data做了判断,如果我在1.html中传过去的数据为“123”,那就可以改变2.html的背景颜色。
oBtn.onclick=function(){
myframe.contentWindow.postMessage('123','http://www.webforend.com/uploads/file')
}
当我再postMessage方法中传入的数据为“123”时,2.html页面的背景颜色发生了改变,变成了红色。跨域通信成功。
我们还可以使用ev.origin判断来源的网站,然后再执行相应的操作