Front-end cross-domain problems are common in large web sites. This paper introduces in detail the principle and application details of using easyXDM to solve the front-end cross domain, which can be extended on the basis of the code examples in the paper.
0, background
Due to HTTP hijacking by some network operators, some important IFrame pop-up pages of the website are inserted with third-party advertisements, which completely block the content and seriously affect the user experience. The company decided to switch these pages to HTTPS. After the switch, it was found that the iframe floating layer automatic sizing function was disabled. The reason was that the main page was HTTP, and the operation on the floating layer size of the parent page was cross-domain after the child window was loaded, which was restricted by the browser. A cross-domain solution is then required to resolve this situation.
1. Cross-domain problems
What is a cross-domain problem? When data request and transmission occur between web pages, as long as any one of the protocol name protocol, host, and port number of two web sites is different, it constitutes a cross-domain. Cross-domain pages cannot, by default, manipulate each other’s page objects directly through JavaScript.
A simple comparison of various cross-domain solutions is as follows:
The above various cross-domain solutions, this article does not do interested students can refer to the deep understanding of front end cross domain method and the principle of “(blog.csdn.net/kongjiea/ar…). .
EasyXDM is recommended here, because easyXDM integrates various existing cross-domain solutions, and well realizes cross-browser compatibility, multiple cross-domain communication parallel, cross-domain request whitelist, communication response and other functions, which can perfectly solve various cross-domain application scenarios.
2. EasyXDM example
Parent page index.html core code:
<div id="container"></div>
<div id="output">
<p>The blue area is the main page content output area</p>
</div>
<script src="easyXDM.min.js"></script>
<script>
var showMsg = function (message) {
document.getElementById('output').innerHTML += "<p>" + message + "</p>";
};
var rpc = new easyXDM.Rpc({
isHost: true.remote: 'http://127.0.0.1/easyXDM/iframe.html'.hash: true.protocol: '1'.container: document.getElementById('container'),
props: {
frameBorder: 0.scrolling: 'no'.style: {width: '100%'.height: '100px'}}}, {local: {
echo: function (message) { showMsg(message); }}});</script>Copy the code
Sub-page iframe.html core code:
<p>Solid wireframes are subpage areas</p>
<button id="btn" value="">Click send data to main page</button>
<div id="output"></div>
<script src="easyXDM.min.js"></script>
<script>
var showMsg = function (message) {
document.getElementById('output').innerHTML += "<p>" + message + "</p>";
};
window.rpc = new easyXDM.Rpc({
isHost: false.//acl: '^(https? : \ \ / \ \ /)? ([a-zA-Z0-9\\-]+\\.) *baixing.com(\\/.*)?$',
protocol: '1'
},
{
remote: {
echo: {}}});document.getElementById('btn').onclick = function () {
rpc.echo('echo from iframe');
};
</script>Copy the code
Visit http://localhost/easyXDM/index.html, because the index. The HTML and iframe. HTML page two different host, child pages operation main page content belongs to cross domain access. With easyXDM as the channel, this operation can be carried out normally, as shown in the picture below:
In a real-world application scenario, modifying the calling function lets the child page do whatever it wants to the parent page.
3, easyXDM principle analysis
3.1 Principles
EasyXDM encapsulates different underlying communication schemes, such as the postMessage() scheme used in the example above for cross-domain bidirectional communication.
3.1.1 Sub-pages send data to the main page
EasyXDM packages the method call operation and sends it to the main page through postMessage(). The message processing function of the main page receives the data and turns it over to easyXDM for parsing and calls the calling function. The code call and data flow are shown below:
Description of data transferred:
defaultXXX
: is the channel identifier. This value does not change if the page is not refreshedid
: Request number, incremented by 1 each time a request is sentmethod
: Specifies the name of the method to callparams
: Parameter of the calling method, expressed in JSON formatjsonrpc
: indicates the jSON-RPC message version
3.1.2 The main page method returns response data
EasyXDM will also call postMessage to send the method response back to the sub-page, and the message processing function of the sub-page will be handed over to easyXDM for parsing after receiving the data, and the corresponding response processing operation will be performed after parsing. The code call and data flow are shown below:
Description of data transferred:
defaultXXX
: is the channel identifier. This value will not change if the page is not refreshed. Consistent with the data sent by the child pageid
: corresponds to the ID sent when the method is calledresult
: Method response, expressed in JSON formatjsonrpc
: indicates the jSON-RPC message version
The code for the main page and sub-pages is explained in detail below.
3.2 Main page call code parsing
When easyXdm.rpc () is called on the home page, the communication component is initialized and the iframe child page is created. Specific parameter meanings are described as follows:
isHost
: true: creates iframe subpagesremote
: Url of the created iframe child pagecontainer
: is a DOM object. The created iframe is contained in the Containerprops
The content specified in the: property is appended to the iframe objecthash
: true indicates that channel-related parameters xdM_e/xdM_c/xdM_p will be recorded in the URL hash, false will become URL parameters; In general, it is recommended to set this value to true because passing cross-domain related front-end parameters to the back-end is not a good way to do this, but it can solve the problem of channel retention after form submission. So specific scene specific choice.
By properly setting the above properties, you can change the iframe written on the page to be loaded via easyxdm.rpc (), thus achieving flexible code embedding.
In the example above, the page elements of the parent page after RPC initialization are as follows:
<div id="container">
<iframe
name="easyXDM_default5491_provider"
id="easyXDM_default5491_provider"
frameborder="0"
scrolling="no"
src="Http://127.0.0.1/easyXDM/iframe.html#xdm_e=http%3A%2F%2Flocalhost& xdm_c=default5491& xdm_p=1"
style="width: 100%; height: 100%;">
</iframe>
</div>Copy the code
The name and ID of iframe are automatically generated to distinguish different RPC channels, which means that multiple cross-domain call channels can be established on a page. The middle xdM_E/xDM_C/xDM_P parameters are initialized channel parameters.
In addition, the local parameter configuration defines the function method name and method implementation that can be called by the sub-page. The method name and method parameters can be arbitrarily specified as required.
3.3 Sub-page call code parsing
The parsing of RPC parameters in iframe is as follows:
isHost
False: indicates that this is the client and does not create an iframe pageprotocol
: Communication protocol: number. For details, see the following communication protocol descriptionacl
: Optional whitelist of code callers’ URLS
Corresponding to the local parameter of the main page, the remote configuration of the sub-page defines the method name of the main page that all the sub-pages need to call. Only defined in remote can be called on a child page via an RPC instance.
EasyXDM is used to communicate with easyXDM, just as rpc.echo() can directly call the echo method defined on the main page.
3.4 Communication Protocol Description
For communication protocols, if not specified in the code configuration, the most recent one will be matched according to the following rules
4
: Indicates direct communication when the two ends belong to the same domain1
: when there iswindows.postMessage
或document.postMessage
(Supported by Internet Explorer 8+, Firefox 3+, Opera 9+, Chrome 2+, and Safari 4+)postMessage
Mechanism of communication6
: SWF attributes exist in the configuration and are supportedwindow.ActiveXObject
Is used to communicate through the configured SWF5
: Used when using Gecko (Firefox 1+window.frameElement
Attribute do communication2
: If remoteHelper is configured, communication is performed using remoteHelper0
: Default, all browsers support; When the above rules are inconsistent, the image loading mechanism is used for communication
4. More functions
4.1 Added request response processing
Add a return value to the index. HTML page echo function:
<script>
new easyXDM.Rpc({
// ...
},
{
local: {
echo: function (message) {
document.getElementById('output').innerHTML += "<p>" + message + "</p>";
return {'msg': 'echo done from index'}; }},remote: {}});</script>Copy the code
Iframe.html calls RPC methods by adding a callback function:
<script>
// ...
document.getElementById('btn').onclick = function () {
rpc.echo('echo from iframe'.function (response) {
showMsg(response.msg);
}, function (errorObj) {
alert('error');
});
};
</script>Copy the code
The effect is shown below:
4.2 Main page Invokes subpage methods
PingIframe = pingIframe = pingIframe = pingIframe;
window.rpc = new easyXDM.Rpc({
// ...
},
{
local: {
pingIframe: function (message) {
showMsg(message);
return {'msg': 'pong from iframe'}}},remote: {
echo: {}}});Copy the code
Register the pingIframe method declaration for the child page in RPC remote in index.html and add the button call event:
<button id="btn" value="">Click send data to child page</button>
<script>
// ...
var rpc = new easyXDM.Rpc({
// ...
},
{
local: {
// ...
},
remote: {
pingIframe: {}}});document.getElementById('btn').onclick = function () {
rpc.pingIframe('ping from index'.function(response){
showMsg(response.msg);
}, function(errorObj){
alert('error');
});
};
</script>Copy the code
The effect is shown below:
4.3 Home Page Communicates with multiple pages
To do multi-page communication, just repeat similar related code calls. In this example, copy the above ifame. HTML as iframe2.html and simply change the text inside to distinguish; At the same time modify the index.html code as follows:
<div id="container"></div>
<button id="btn" value="">Click send data to subpage 1</button>
<button id="btn2" value="">Click Send data to subpage 2</button>
<div id="output">The blue area is the main page content output area</div>
<script src="easyXDM.min.js"></script>
<script>
var showMsg = function (message) {
document.getElementById('output').innerHTML += "<p>" + message + "</p>";
};
var generateRpc = function (url) {
return new easyXDM.Rpc({
isHost: true.remote: url,
hash: true.protocol: '1'.container: document.getElementById('container'),
props: {
frameBorder: 0.scrolling: 'no'.style: {width: '100%'.height: '100px'}}}, {local: {
echo: function (message) {
showMsg(message);
return {'msg': 'echo done from index'}; }},remote: {
pingIframe: {}}}); };var bindRpc = function(rpc, btnId) {
document.getElementById(btnId).onclick = function () {
rpc.pingIframe('ping from index'.function (response) {
showMsg(response.msg);
}, function (errorObj) {
alert('error');
});
};
};
var rpc1 = generateRpc('http://127.0.0.1/easyXDM/iframe.html');
bindRpc(rpc1, 'btn');
var rpc2 = generateRpc('http://127.0.0.1/easyXDM/iframe2.html');
bindRpc(rpc2, 'btn2');
</script>Copy the code
The effect is shown below:
4.4 IFrame Keeps RPC Communication after switching pages
With hash set to false and no additional processing, when you submit a form from a child page or click a hyperlink from a child page to open a new page, you will find that communication with the parent window is broken. The reason is that the xDM_E/XDM_C/XDM_P parameters related to the communication channel are lost after the page switch, resulting in the failure to maintain communication. The solution is to pass the channel parameters in the newly opened page url. For convenience, jQuery library is introduced as follows:
/* Add the following code to the subpage * 2. Add easyXDM class name in the form or A tag of the sub-page, and pass easyXDM parameter to the new page via url * to keep cross-domain communication after page jump */
$(document).ready(function () {$('form.easyxdm').each(function () {
var $form = $(this);
var action = $form.attr('action');
$form.attr('action', action + window.location.hash);
});
$('a.easyxdm').each(function () {
var $link = $(this);
var href = $link.attr('href');
$link.attr('href', href + window.location.hash);
});
});Copy the code
5. Debug easyXDM library
If some unknown errors are encountered in the process of using easyXDM library, front-end debugging can be done by loading the debugging library, and the steps are as follows:
- From the easyXDM GitHub library (github.com/oyvindkinse…) Pull the full branch
- will
src
Directory to copy to its own code directory - Change to import where easyXDM libraries are introduced
easyXDM.debug.js
- You can then use the Chrome browser for JavaScript debugging. Detailed debugging method in this paper, do not do, interested students can refer to the front-end Chrome debugging summary (www.jianshu.com/p/b25c5b88b)… The Sources Resource page breakpoint Debugging section.
Download the complete code for this article: pan.baidu.com/s/1cpRlim
6, endnotes
Because the easyXDM library itself readme. md has not been maintained and updated for a long time, some parameter meanings cannot be found; The document does not explain the realization of the principle, the author encountered many problems in the process of using, can only be solved by code debugging and reading the code to deeply understand the realization of the principle. This article is the author to use easyXDM some summary, for your reference.
7. Reference Documents:
- EasyXDM website easyxdm.net
- EasyXDM making library github.com/oyvindkinse…
Author: Nan Zhimin Profile: people net revenue technical team member.
This article is the author’s personal view only, does not represent the people’s net position. Pic2. Me
This article is published on the wechat public account of “People’s Net Technical Team”. Scan the code to subscribe immediately: