As you probably know, you can’t send AJAX (XMLHttpRequest) requests to another domain. Browsers block it because of the Same Origin Policy, a rule used to make sure that a malicious script won’t be able to access data on other pages.
This can be a problem, however, if you need to load data for a widget from another domain. For instance, suppose you are developing a widget that your partners will use on their websites and it will load data from your server.
A really clever solution is called JSONP, which stands for “JSON with Padding.” It works by “exploiting” the fact that <script> tags can load files from other domains.
Here’s a simple example of how it works:
1. Create your HTML file (On Domain A)
<html>
<body>
<h1 id="maintitle><h1>
</body>
</html>
As you can see, it has no title. We are going to get the title from another website, and put it there using JavaScript.
2. Create a JavaScript function to change the title (On Domain A)
<html>
<body>
<h1 id="maintitle><h1>
<script>
function changeTitle(data){
document.getElementById("maintitle").innerHTML = data.title;
};
</script>
</body>
</html>
Notice that this functions receives a parameter “data” which contains the title, and then changes it on the HTML.
3. Create the server side script that returns the data (On Domain B)
<?php
if($_GET['callback']){
$f_name = $_GET['callback'];
echo "$f_name({'title':'Hello World!'});";
}
else{
echo "Error: You must pass a callback parameter";
}
?>
This script checks whether a GET parameter called ‘callback’ was provided. In positive case, it returns a JavaScript function named after that parameter, and the title as data (in this example the title is “Hello World”).
Now suppose we put that script on serverdomain.com/server.php. If we opened serverdomain.com/server.php?callback=ChangeTitle the server would send back the following:
ChangeTitle({'title':'Hello World'});
This is the same name of the JavaScript function we created on step 2. That is no coincidence. You are going to see why now.
4. Use another <script> tag to load the data from the other server (On Domain A)
<html>
<body>
<h1 id="maintitle><h1>
<script>
function changeTitle(data){
document.getElementById("maintitle").innerHTML = data.title;
};
</script>
<script src="http://serverdomain.com/server.php?callback=ChangeTitle"></script>
</body>
</html>
The second <script> tag will ping our server and essentially load this code:
ChangeTitle({'title':'Hello World'});
This will call the ChangeTitle function defined on the first <script> tag with our title as a parameter, and that function will then change the title of the HTML.
Nice huh?
5. Making the Request Dynamically
The example above makes the request by placing a <script> manually on the HTML of the page. You can also do that dynamically with JavaScript, which becomes quite handy for dynamic web applications:
function myFunction(data)
{
//do stuff
}
var script = document.createElement('script');
script.src = 'http://example.com/?callback=myFunction';
document.getElementsByTagName('head')[0].appendChild(script);
The code below will also work on newer browsers:
document.head.appendChild(script)
Common problems:
1. Notice that both domains must be using the same protocol (HTTP or HTTPS), else you’ll get an error.