HTML5 postMessage cross-origin exchange data
The preface briefly explains how to use the script tag (jsonp) and iframe tag (window. name, location. hash) to exchange data across domains. Today we will learn about HTML5 APIs and use postMessage to exchange data across domains. Unlike the previous data exchange methods, postMessage cannot exchange data with the server, but can only exchange data between two windows (iframe. PostMessage overview: postMessage is used to exchange data between two windows (iframe). If we open both Baidu and Google pages, does it mean that the two can communicate with each other? No, no, no, this is not the case, even if Baidu and Google have the willingness to communicate. The premise that two windows can communicate is that a window exists in the form of iframe in another window, or a window passes through the window from another window. opened in the form of open () or hyperlink (you can also use window. opener obtains the source window). In other words, to exchange data, you must be able to obtain the reference of the target window. Otherwise, there is no connection between the two windows and there is nothing to do with communication. Since it is from the H5 family, we have to wait and see how much it is accepted by the majority of browsers (check can I use postMessage for details). We can see that the acceptance level is quite high: the usage of postMessage is also quite simple: otherWindow. postMessage (message, targetOrigin, [transfer]); otherWindow is a reference to the receiver window. Generally, it can be in the following ways: window. frames [0]. postMessagedocument. getElementsByTagName ('iframe') [0]. contentWindowwindow. opener. postMessageevent. source. postMessagewindow. reference returned by open... message, as its name implies, is the content of the sent data. It supports almost all forms of data, such as strings, numbers, and json. (For details, refer to T. He structured clone algorithm) targetoriginis the receiver's uri(, it can also be a urlform, And the content (such as xx.html) is automatically ignored. Wildcards * can be used to specify all domains, but do not use (for security ). Transfer can be omitted. If you do not understand what it means, you can study it later and listen to message events in the receiver window. For details, see the example below. Window <-> iframe suppose that the index page has an iframe (different from the same source). We want to send data to iframe, and iframe also sends data to the top window after obtaining the data, indicates that "I" has obtained the data. Read the source code directly (think about how to send and receive it): copy the Code <! -- http://localhost:81 /Fish/index.html --> <script type = "text/javascript"> // After the page is loaded, the dom node (iframe) window can be obtained. onload = function () {// send data document to the target source. getElementsByTagName ('iframe') [0]. contentWindow. postMessage ({"age": 10 },' http://localhost:8080 ') ;}; // Listen for any data sent to the window. addEventListener ('message', function (e) {console. log (e) ;}); </script> <iframe src =" http://localhost:8080 /Index.html "> </iframe> copy the Code <! -- http://localhost:8080 /Index.html --> <script type = "text/javascript"> // listen for any data sent to window. addEventListener ('message', function (e) {// determine whether the data sender is a reliable address if (e. origin! =' http://localhost:81 ') Return; // print the console data format. log (e); // resend data e. source. postMessage ('Hello world', e. origin) ;}, false); </script> copy the code to see what the print looks like (the data that the index page passes to iframe ): the red box shows the three most important attributes. data, as its name implies, is the data transmitted. origin is the source of the message sending window (URI protocol + host + port ); the source can reference the window object for sending messages (it can be used to reference the sending window for message return ). You can listen to message events on the message receiving end (the code above). If you want to be compatible with ie, you must use attachEvent. Window. onmessage is not recommended here, and its compatibility is not good (for example, it is not compatible with earlier ff versions ). Window <-> window refers to the data exchange with iframe on the same page. Let's talk about the data exchange between the two windows. We know that window is used. open () can open a new window, and if the two windows are the same, the communication between the two windows will be very simple, we can use the window. opener. functionName calls the method (and variable) of the original window in the new window ). However, if the two windows are different from each other, this operation will become very difficult. Fortunately, H5 provides us with postMessage so that window. opener. postMessage () will not report an error! Demo is simple:
<! -- Http: // localhost: 81/fish/index.html --> <script type = "text/javascript"> // open a new window var popup = window. open ('HTTP: // localhost: 8080/index.html '); // When the popup has fully loaded, if not blocked by a popup blocker: setTimeout (function () {// the current window transmits data popup to the target source. postMessage ({"age": 10}, 'HTTP: // localhost: 8080 ') ;}, 1000); </script>
<! -- Http: // localhost: 8080/index.html --> <script type = "text/javascript"> // set the listener. If there are several pieces of data, print the window. addEventListener ('message', function (e) {console. log (e); // console. log (e. source = window. opener); // true}); </script>
The reason for setting a timer is that sending data to the target window must wait until the target window is fully loaded. That is to say, you must set the "listener" in the target window ", only the data sent in the sending window can be monitored. Therefore, a timer delay is provided, and the delay value of the timer cannot be determined because of the uncertain loading time; another feasible method is to send a message to the Source Page (postMessage) after the target page is loaded. The source page receives the message and then sends the message to the target page using postMessage. When security concerns mention cross-Origin data exchange, the condition reflection will always ask, is it safe? For postMessage, the answer is yes. PostMessage adopts a two-way security mechanism ". When the sender sends data, it will confirm the source of the receiver (so it is best not to use *). After the receiver monitors the message event, it can also use the event. determines whether the origin is from a correct and reliable sender.