Implementation principle of Ajax cross domain communication using iframe (illustration)

Time:2021-10-20

In the long journey of front-end development, it is inevitable to come into contact with Ajax, and generally Ajax requests are used in the same domain; However, if the request occurs in different domains, the request cannot be executed, and an exception prompt will be thrown. Cross domain requests are not allowed. At present, I have not found clear information to explain why. I think it should be for security reasons. Even so, there are still more than one method to achieve cross domain access. Here is one solution: how to use iframe to complete Ajax cross domain requests.

As shown in the following figure: the page request.html of domain a.com (i.e http://a.com/request.html )An iframe is nested inside to point to the response.html of domain b.com, and the proxy.html of domain a.com is nested in response.html.

To implement the request.html of domain a.com and the process.php of domain b.com, you can pass the requested parameters to response.html through the URL. Response.html sends a real Ajax request to process.php (both response.html and process.php belong to domain b.com), and then pass the returned results to proxy.html through the URL. Finally, because proxy.html and request.html are in the same domain, Therefore, you can use window.top in proxy.html to return the results to request.html to complete cross domain communication.

The idea of the whole process is actually very clear. The real Ajax request does not occur in domain a.com, but in domain b.com; Domain a.com does two things. The first is completed by request.html and sends the incoming parameters to domain b.com; The second reason is to complete proxy.html and return the response data of domain b.com to request.html.

Cross domain access flowchart

OK, the next step is how to implement it in code; Before that, look at the document structure:

http://a.com/

request.html

proxy.html

http://b.com/

response.html

process.php

1. Let’s take a look at request.html. To facilitate understanding, I also put JS on the page:

Copy codeThe code is as follows:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
< title > the path of this page is: http://a.com/request.html </title>
</head>
<body>
<p>The result of the response will be filled in here</p>
< a href = “javascript: void (0)” > Click to send a cross domain request</a>
<iframe></iframe>
<script type=”text/javascript”>
document.getElementById(“sendBtn”).onclick = function() {
var url = “http://b.com/response.html”;
var fn = “GetPerson”;// This is the method defined in response.html
var reqdata = ‘{“id” : 24}’;// This is the requested parameter
var callback = “CallBack”;// This is the callback function executed after the whole process of the request is completed to execute the final action
CrossRequest(url, fn, reqdata, callback);// Send request
}
function CrossRequest(url, fn, reqdata, callback) {
var server = document.getElementById(“serverIf”);
server.src = url + “?fn=” + encodeURIComponent(fn) + “&data=” + encodeURIComponent(reqdata) + “&callback=” + encodeURIComponent(callback);// The request sent from request.html to response.html is actually to pass parameters and callback methods to response.html through the SRC of iframe
}
Function callback (data) {/ / callback function
var str = “My name is ” + data.name + “. I am a ” + data.sex + “. I am ” + data.age + ” years old.”;
document.getElementById(“result”).innerHTML = str;
}
</script>
</body>
</html>

It’s easy to understand from the code and comments. This page actually tells response.html: I want you to execute the method getperson you defined, and use the parameter ‘{“Id”: 24}’ I gave you. What you may feel vague is why you want to pass the callback function to response.html, which is a method defined on this page, and response.html cannot execute it; You can see from the following code: response.html is purely responsible for passing the method name of callback to the next brother proxy.html, and proxy.html can execute after getting the method name of callback, because proxy.html and request.html are in the same domain.

2. Next, let’s look at the code of response.html:

Copy codeThe code is as follows:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
< title > the path of this page is: http://b.com/response.html </title>
</head>
<body>
<iframe></iframe>
<script type=”text/javascript”>
function _ Request (reqdata, URL, callback) {/ / general method, AJAX request
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else {
xmlhttp = new ActiveXObject(“Microsoft.XMLHTTP”);
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var data = xmlhttp.responseText;
callback(data);
}
}
xmlhttp.open(“POST”, url);
xmlhttp.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
xmlhttp.send(reqdata);
}
function _ Getquery (key) {/ / general method to obtain URL parameters
var query = location.href.split(“?”)[1];
var value = decodeURIComponent(query.split(key + “=”)[1].split(“&”)[0]);
return value;
}
Function getperson (reqdata, callback) {/ / send Ajax request to process.php
var url = “process.php”;
var fn = function(data) {
var proxy = document.getElementById(“proxy”);
proxy.src = “http://b.com/Proxy.html?data=” + encodeURIComponent(data) + “&callback=” + encodeURIComponent(callback);
}
_request(reqdata, url, fn);
}
(function() {
var fn = _getQuery(“fn”);
var reqdata = _getQuery(“data”);
var callback = _getQuery(“callback”);
eval(fn + “(‘” + reqdata +”‘, ‘” + callback + “‘)”);
})();
</script>
</body>
</html>

In fact, this is to receive the request from request.html, get the request parameters and methods, send a real Ajax request to the server process.php, and then pass the data returned from the server and the callback function name passed from request.html to proxy.html.

3. Next, let’s look at the code of process.php, which is relatively simple:

Copy codeThe code is as follows:
<?php
$data = json_decode(file_get_contents(“php://input”));
header(“Content-Type: application/json; charset=utf-8”);
echo (‘{“id” : ‘ . $data->id . ‘, “age” : 24, “sex” : “boy”, “name” : “huangxueming”}’);
?>

I’m not going to talk about these sentences of code. I can understand a little bit of PHP foundation. I should be able to see a general idea if I don’t have PHP foundation. Ha ha ~ ~

4. Finally, proxy.html:

Copy codeThe code is as follows:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
< title > the path of this page is: http://a.com/proxy.html </title>
</head>
<body>
<script type=”text/javascript”>
function _ Geturl (key) {/ / general method to obtain URL parameters
var query = location.href.split(“?”)[1];
var value = decodeURIComponent(query.split(key + “=”)[1].split(“&”)[0]);
return value;
}
(function() {
var callback = _getUrl(“callback”);
var data = _getUrl(“data”);
eval(“window.top.” + decodeURIComponent(callback) + “(” + decodeURIComponent(data) + “)”);
})()
</script>
</body>
</html>

This is also the last step. The proxy finally gets the callback function name transmitted from request.html through response.html and the response data directly transmitted from response.html, and uses window.top to execute the callback function defined in request.html.

In practical application, proxy.html can basically be a general proxy without modification. If many cross domain methods need to be used, these methods can be added in domain a.com, and domain b.com is equivalent to defining some interfaces for a.com to call, such as getperson. Of course, this is not a real interface, but easy to understand, for example; In addition, of course, the iframe should be hidden. OK, finally, I still offer the old saying: the technology is not the most important, the most important thing is the ability to learn.

Recommended Today

Swift advanced (XV) extension

The extension in swift is somewhat similar to the category in OC Extension can beenumeration、structural morphology、class、agreementAdd new features□ you can add methods, calculation attributes, subscripts, (convenient) initializers, nested types, protocols, etc What extensions can’t do:□ original functions cannot be overwritten□ you cannot add storage attributes or add attribute observers to existing attributes□ cannot add parent […]