I recently encountered a need at work. The scenario is: the h5 page is embedded in the PC page as a preview module. The user can do some operations on the PC page, and then the h5 page makes responsive changes to achieve the preview effect.
The first thing that comes to mind here is to embed the h5 page into the pc web page using an iframe, and then the pc sends the changed data to the iframe through the postMessage method. The h5 embedded in the iframe receives the data through addEventListener, and then makes responsive changes to the data.
Here is a summary of the use of postMessage. The API is very simple:
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
is a reference to the target window, which is iframe.contentWindow in the current scenario;
message
is the message sent. Before Gecko 6.0, the message must be a string, but later versions can send the object directly without serializing it yourself;
targetOrigin
represents the origin of the target window, and its value can be a string * (indicating unlimited) or a URI. When sending a message, if any of the protocol, host address or port of the target window does not match the value provided by targetOrigin, the message will not be sent; only if the three completely match, the message will be sent. For confidential data, it is very important to set the target window origin;
When postMessage() is called, a message event is dispatched to the target window. This interface has a message event, which has several important properties:
1.data: As the name suggests, it is the message passed in
2.source: the window object that sends the message
3.origin: the source of the message window (protocol + host + port number)
In this way, we can receive cross-domain messages, and we can also send messages back in a similar way.
The optional parameter transfer is a string of Transferable objects that are passed along with the message. The ownership of these objects will be transferred to the receiver of the message, and the sender will no longer retain ownership.
Then, when iframe
is initialized, you can get the reference to the iframe and send the message through the following code:
// Note that this is not to get the dom reference of the iframe, but the reference of the iframe window const iframe = document.getElementById('myIFrame').contentWindow;iframe.postMessage('hello world', 'http://yourhost.com' );
In an iframe, the message can be received through the following code.
window.addEventListener('message', msgHandler, false);
When receiving, you can filter the message origin as needed to avoid XSS attacks caused by receiving messages with illegal domain names.
Finally, for code reuse, message sending and receiving are encapsulated into a class, and the message type API is simulated, which is very convenient to use. The specific code is as follows:
export default class Messager { constructor(win, targetOrigin) { this.win = win; this.targetOrigin = targetOrigin; this.actions = {}; window.addEventListener('message', this.handleMessageListener, false); } handleMessageListener = event => { if (!event.data || !event.data.type) { return; } const type = event.data.type; if (!this.actions[type]) { return console.warn(`${type}: missing listener`); } this.actions[type](event.data.value); } on = (type, cb) = > { this.actions[type] = cb; return this; } emit = (type, value) => { this.win.postMessage({ type, value }, this.targetOrigin); return this; } destroy() { window.removeEventListener('message', this.handleMessageListener); }}
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.