目录
第一章 前言
在H5/移动端/pc开发的过程中会遇到一个很常见的问题,就是经常会将一个写好的项目用iframe嵌到另一个项目中。这个时候小编就有疑问了,我们如何才能获取到嵌套在内部页面的数据或者参数呢?它们之间如何在不同域的不同网页或框架安全地相互交互?接下来小编将使用postMessage的两种方法,为大家解决一下疑惑。
第二章 弄懂postMessage两个方法
2.1 window.postMessage
该方法是一种安全的方式,可以实现不同源(域)的两个窗口(或标签页)之间的通信。
- 它允许一个窗口的脚本安全地向另一个窗口传递消息,即使它们来自不同的域。
- 对于Web应用程序中嵌入第三方小部件、iframe或跨源通信特别有用。
- 发送消息的窗口,语法:
window.postMessage(message, targetOrigin, [transfer])
- window:当前窗口的引用,可以是iframe或window对象。
- message:要发送的数据,可以是任何可以序列化的JavaScript对象。
- targetOrigin:消息的目标源,只有目标窗口与指定的源相同才会接收到消息(常用)。如果是字符串"*",表示接收任何源的消息(特殊)。
- transfer(可选):要转移的对象,如Blob和ArrayBuffer。
-- 端口5501引入了端口5500的页面,端口5500给端口5501发送数据
<!--
origin: http://127.0.0.1:5500
targetOrigin: http://127.0.0.1:5501
origin发消息到targetOrigin: origin => targetOrigin
-->
<!DOCTYPE html>
<html>
<head>
<title>Origin 1</title>
</head>
<body>
<button onclick="sendMessage()">Send Message</button>
<script>
function sendMessage() {
const message = 'Hello from Origin 1!';
const targetOrigin = 'http://127.0.0.1:5501';
window.postMessage(message, targetOrigin);
}
</script>
</body>
</html>
- 接收消息,监听message,端口5500发送的
window.addEventListener('message', (e) => {})
-- 端口5501嵌入了5500的页面,监听数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>5001页面</div>
<iframe src="5000页面地址" />
<script>
// 监听 message 的变化
window.addEventListener('message', (e) => {
if (e.origin === 'http://127.0.0.1:5500') { // (安全判断)接收来自 http://127.0.0.1:55010 网页的信息
console.log('信息:', e)
}
})
</script>
</body>
</html>
2.2 window.parent.postMessage
- 该window.parent.postMessage方法类似于window.postMessage方法,但它专门用于在嵌入的 iframe 中与其父窗口进行通信。
- 用法与2.1一样:
window.parent.postMessage(message, targetOrigin, [transfer]);
- message:发送复杂数据,比如对象或数组。该方法支持 JSON 可序列化的数据,可以将 JavaScript 对象和数组作为消息内容传递。只需确保数据可以在 iframe 和父窗口之间安全地序列化和反序列化。
- targetOrigin:指定父窗口的来源。
- transfer(可选):与window.postMessage一样,此参数允许在发送时传输数据而不是克隆。
- 实战例子:
-- 子页面
-- 后端调用:父页面
-- 获取到的数据
- 这里重点介绍event对象的四个常用的属性:
- data : 指的是从其他窗口发送过来的消息对象
- type: 指的是发送消息的类型
- source: 指的是发送消息的窗口对象
- origin: 指的是发送消息的窗口的源
第三章 总结
总之,当遇到跨页面嵌入时,遇到需要获取消息的问题,或者根据子页面的某些按钮需要父组件执行某些操作等等,一定要想到这两个方法!!!