背景
最近公司要求所有产品付款页面输入卡号密码信息的部分必须采用公司的统一页面。
具体实现方案是,我们将公司统一的输入卡号密码的页面通过iframe嵌入我们产品的付款页面。用户点击付款时,我们需要给iframe的页面发送消息,通知他们可以进行付款处理了。
我们产品页面与iframe内嵌的页面之间是不同域的页面。所以在通知iframe付款时,我们采用了window.postMessage
方法进行通信。
window.postMessage方法介绍
假如我们的页面的window对象引用是windowParent
,内嵌在iframe的页面的window对象引用是windowCard
。
付款时,我们需要给他们发送数据:
windowCard.postMessage(message, targetOrigin, [transfer]);
- message: 给目标页面发送的数据。格式可以是各种数据对象。目前我们发送的格式为
JSON
字符串。 - targetOrigin: 通常是字符串"*"或者一个URI,指定允许哪些域能接收到消息。如果采用
*
,那么意味着允许把数据发送到任一个站点。所以,如果我们明确知道目标页面的域,那么将域的URL给这个参数是更为安全的做法。 - transfer(可选): “是一串和message同时传递的Transferable对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权”。
我们在发送消息给目标页面之后,目标页面进行数据处理,处理完毕后会将处理结果返回给我们的页面。
他们同样用window.postMessage
给我们发送处理结果。我们通过给我们页面的message
事件增加event handler
来接收处理结果。
windowParent.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
var data = event.data;
var origin = event.origin;
var source = event.source;
}
如上所示,event的属性有:
- data: 数据对象。目标页面会将她们的处理结果等等信息放在这里。
- origin:
postMessage
发送方的origin
。该字符串为协议
、域名
和端口号
拼接而成。 - source:
postMessage
发送方的window
对象的引用。
样例代码(不可运行)
<div id="MyPage">
<iframe id="checkout" url="checkout.mycompany.com/uniformcheckoutpage"></iframe>
<input type="text" id="name" />
<input type="text" id="address" />
<input type="button" id="pay" />
<div>
<script type="text/javascript">
document.querySelector("#pay").addEventListener("click", MakePayment, false);
window.addEventListener("message", ReceiveMessage, false);
function MakePayment() {
var name = document.querySelector("#name");
var address = document.querySelector("#address");
windowCard.postMessage(JSON.stringify({name : name, address : address}), "checkout.mycompany.com");
}
//Assume the target frame send back response with result and errorMessage
function ReceiveMessage(event) {
var result = event.data.result;
var result = event.data.errorMessage;
}
</script>
参考:
[1] https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
网友评论