Cross‑Origin Communication Techniques: JSONP, window.name, document.domain, CORS, postMessage, and WebSocket with Code Samples
This article demonstrates several cross‑origin communication methods—including JSONP, window.name, document.domain, CORS, postMessage, and WebSocket—by providing step‑by‑step code examples, host file configuration, and instructions for testing each technique in a local environment development.
Example Details
To test cross‑origin techniques locally, modify the hosts file to map several domain names to 127.0.0.1:
127.0.0.1 source.test.com
127.0.0.1 target.test.com
127.0.0.1 source.test.org
127.0.0.1 target.test.orgAll examples can be downloaded from the provided link.
JSONP
Source page source.test.com/source-client.html loads a script that creates a dynamic callback function and appends a <script> element pointing to the target domain.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp Test</title>
<script type="text/javascript">
function getJSON(url,callback){
var script = document.createElement('script');
var callbackName = "ProxyFunc_" + (new Date()).getTime();
window[callbackName] = function(){
callback(arguments[0]);
};
script.onload = script.onratechange = function(){
if(this.readyState == 'complete'){
window[callbackName] = null;
}
};
script.src = url.replace("JSONPCallback",callbackName);
document.head.appendChild(script);
}
getJSON("http://target.test.org:9000/getData.do?callback=JSONPCallback",function(data){
console.log(data);
});
</script>
</head>
<body></body>
</html>Target server (Node.js) reads the callback query parameter and returns a JavaScript snippet that invokes the callback with JSON data.
var http = require("http");
var url = require("url");
var server = new http.Server();
server.listen(9000);
server.on("request", function(request, response) {
var paramDict = url.parse(request.url, true).query;
var callback = paramDict.callback;
var retData = callback + '(' + '{"status":"success",data:{"name":"test JSONP"}}' + ')';
response.end(retData);
});Open the source page and view the console to see the received data.
window.name
The source page sets window.name and then redirects to the target page; the target page can read the same window.name value even after navigation.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>window.name test</title>
<script type="text/javascript">
window.name = "source shared windowname";
alert(window.name);
window.location.href = "http://target.test.org/target.html";
</script>
</head>
<body></body>
</html> <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>window.name test</title>
<script type="text/javascript">
alert(window.name);
</script>
</head>
<body></body>
</html>Open the source page and observe that the data persists after the redirect.
document.domain
Both source and target pages set document.domain = "test.com" so that they share the same origin and can manipulate each other's DOM.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>document.domain test</title>
<iframe src="http://target.test.com/target.html"></iframe>
<script type="text/javascript">
document.domain = "test.com";
window.onload = function(){
var doc = window.frames[0].document;
console.log(doc.getElementById('tid').outerHTML);
console.log(doc.body.innerHTML);
setTimeout(function(){
doc.body.innerHTML = "data from source.test.com";
},3000);
};
</script>
</head>
<html> <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>document.domain test</title>
<script type="text/javascript">
document.domain = "test.com";
</script>
</head>
<body>
<p id="tid">data of target.test.com</p>
</body>
</html>Open the source page and inspect the console to see the target page’s DOM.
CORS
The source page sends an XMLHttpRequest to http://target.test.org:9000/getInfo.json . The target Node.js server adds the Access-Control-Allow-Origin header to permit the request.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cross domain resource sharing test</title>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}
};
xhr.open('POST','http://target.test.org:9000/getInfo.json',true);
xhr.send();
</script>
</head>
<body></body>
</html> var http = require("http");
var server = new http.Server();
server.listen(9000);
server.on("request", function(request, response){
// add CORS header
response.setHeader("Access-Control-Allow-Origin", "http://source.test.com");
response.writeHead(200,{"Content-Type":"text/html;charset=UTF-8"});
response.write('msg: "cross origin by cors"');
response.end();
});Deploy both files, open the source page in a browser, and view the request/response in the developer console.
postMessage
The source page embeds the target page in an iframe and uses window.addEventListener('message', …) to exchange messages.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>postMessage Test Source</title>
<script type="text/javascript">
window.addEventListener('message',function(evt){
console.log('source getmessage:',evt.data);
evt.source.postMessage('##source message##',evt.origin);
});
</script>
</head>
<body>
<iframe src="http://target.test.org/target.html"></iframe>
</body>
</html> <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>postMessage Test Target</title>
<script type="text/javascript">
window.addEventListener('message',function(evt){
console.log('target getmessage:',evt.data);
});
window.parent.postMessage('##target message##','http://source.test.com');
</script>
</head>
<body></body>
</html>Deploy the two files, open the source page, and observe the exchanged messages in the console.
WebSocket
The target server runs a WebSocket server on port 9000. The source page creates a WebSocket connection, sends a message on open, and logs received messages.
var WebSocketServer = require('ws').Server;
var socketServer = new WebSocketServer({port:9000});
socketServer.on('connection', function(websocket){
websocket.on('message', function(message){
console.log(new Date().getTime(),' received ',message);
websocket.send('###' + message + "###");
});
}); var websocket = new WebSocket("ws://target.test.org:9000");
websocket.onopen = function(){
console.log('websocket opened');
websocket.send('I am opened');
};
websocket.onmessage = function(evt){
console.log('receive message');
console.log(evt.data);
};
websocket.onclose = function(){ console.log('websocket closed'); };
websocket.onerror = function(){ console.log('websocket meets error'); };Install the ws package, start the server with Node, open the source page, and watch the console for bidirectional messages.
References
RFC 6454 The Web Origin Concept
W3C Same‑Origin Policy
MDN CORS documentation
《Web之困‑现代Web应用安全指南》
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.