One of the restrictions imposed by all browser side programming languages is that one cannot make cross-domain ajax requests. This restriction comes because of the same origin policy and even sub-domain ajax calls are not allowed. In this blog post, I will demo two methods of making cross-sub-domain ajax requests. First demo will use mod_proxy module of Apache. While the second demo will use iframe and javascript tricks for making sub-domain ajax requests.
Using mod_proxy for cross-domain ajax requests
By enabling mod_proxy module of apache2, we can configure apache in reverse proxy mode. In reverse proxy mode, apache2 appears be like an ordinary web server to the browser. However depending upon the proxy rules defined, apache2 can make cross-domain request and serve data back to the browser.
Demo Link for Cross Domain Ajax using Apache mod_proxy
In this demo, I will make cross-domain request to http://gtalkbots.com/reverse-proxy-data.php. To make this cross-domain request successful, I have configured apache2 as shown below:
- Enable mod_proxy module.
$ a2enmod proxy $ a2enmod proxy_http $ a2enmod proxy_connect
- Add the following lines to httpd.conf:
$ cat /private/etc/apache2/httpd.conf | grep mod_proxy LoadModule proxy_module libexec/apache2/mod_proxy.so LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
- Create a file reverse-proxy.conf and add the following config:
$ cat /private/etc/apache2/other/reverse-proxy.conf ProxyRequests Off <Proxy *> Order deny,allow Deny from all Allow from .abhinavsingh.com </Proxy> ProxyPass /webdemos/crossdomainajax/reverse-proxy-get.php http://gtalkbots.com/reverse-proxy-data.php ProxyPassReverse /webdemos/crossdomainajax/reverse-proxy-get.php http://gtalkbots.com/reverse-proxy-data.php
In brief, when Apache sees an incoming ajax request to /webdemos/crossdomainajax/reverse-proxy-get.php , it simply proxy pass it to http://gtalkbots.com/reverse-proxy-data.php and return back the response. The whole process is hidden from the users on the demo page.
Using iframes for cross-domain ajax requests
Another method of achieving sub-domain ajax requests is by using iframes. However, javascript does not allow communication between two frames if they don’t have same document.domain. The simplest of the hacks to make this communication possible is to set document.domain of the iframe same as that of the parent frame.
Demo Link for Sub-Domain Ajax using iFrames
In this demo, I will make a sub-domain request to http://img1.abhinavsingh.com/iframe-data.php. To make this possible, I load an iframe with src="http://img1.abhinavsingh.com/iframe-demo.php" and set document.domain="abhinavsingh.com"; for the iframe.
iframe-demo.php
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($) {
function getTimestamp() {
$.get(ajax_url,
{},
function(data) {
$('#iframe_ajax_data', top.document).html('Server time received through iframe ajax: '+data);
}
);
}
document.domain = "abhinavsingh.com";
$('#link', top.document).click(function() {
getTimestamp();
});
});
</script>
In brief, iframe-demo.php sets an onclick event on $('#link' top.document) , which makes a sub-domain ajax request to http://img1.abhinavsingh.com/iframe-data.php
Enjoy!
Abhi's Weblog is a collection of blog articles written by
Hey,
I think we can make cross domain ajax request using jsonp.
http://docs.jquery.com/Release:jQuery_1.2/Ajax
Reply
Yup right, thats why the title reads “using mod_proxy and iframes”
Reply
manish
Ok
Also i couldnt understand the second method.
It seems, you are making a ajax request inside an iframe. The URL of iframe is http://img1.abhinavsingh.com/iframe-demo.php and the ajax request in also to url http://img1.abhinavsingh.com/iframe-data.php. Both are same domain?
Abhinav Singh
The second method deals with cases when you want to fetch data from a sub-domain. You can’t make an ajax call directly from the parent page, hence you do it through iframes.
Consider case of facebook chat. If you see in firebug all chat related ajax are sent to channel.facebook.com which is achieved by the tricks in the second demo.
manish
Ohk.. now i get it..
But its not actually cross browser then, to a user it may appear to be cross browser. I mean, i cant use this method to get data of some 3rd party website which is not mine (this is mostly where cross domain ajax request would come into play).
manish
Any ways thanks for post, got to know news ways for cross domain ajax.
Abhinav Singh
Probably you missed, 1st demo is for cross-domain and 2nd demo is for sub-domain ajax requests.
Stay tuned as I plan to explore more on the same lines in my next few posts.
guy
For the mod_proxy approach, what IP address will the target server [gtalkbots.com] see if I go to your demo page and run it? Will the target server see my IP or your server’s IP?
If it’s your server’s, then there’s no point in using mod_proxy.
Thanks.
Abhinav Singh
Though currently both gtalkbots.com and this blog on same server, i don’t have any data to prove this.
But i believe you will get ip of abhinavsingh.com and not gtalkbots.com in case they were on hosted on different ip servers.
Response header also only include abhinavsingh.com and have no sign that it proxied the request to gtalkbots.com internally.
guy
I’m interested in finding out. I was reading about mod_ip_forwarding, which claims to replace the proxy server ip with that of the client.
But if mod_proxy takes care of that, then there’s no need for additional modules.
If you’d be kind to modify http://gtalkbots.com/reverse-proxy-data.php to return the REMOTE_ADDR server variable, I could try the demo from my server (pc).
Let me know.
guy
Good news! I enabled mod_proxy on my personal server then accessed an external url (different server) and the REMOTE_ADDR value is the client IP address.
However, there are some additional headers: ["HTTP_X_FORWARDED_FOR"]=>
string(9) “127.0.0.1″
["HTTP_X_FORWARDED_HOST"]=>
string(14) “localhost:8080″
["HTTP_X_FORWARDED_SERVER"]=>
string(11) “192.168.1.2″
As you can see, the proxy server ip and hostname are passed to the target server. Thus, I’m assuming mod_ip_forwarding specifically resolves that by NOT passing the proxy server info — which is a highly desirable thing!
I don’t want the target server to even know about the proxy server. But I guess it’s ok for most situations — wherein only the REMOTE_ADDR value will be used by target servers.
I have yet to install mod_ip_forwarding to see if it does the job, but I’d like to test it out.
Thanks for the article, mate. This is a game changer for cross-scripting until future browsers support it on the client-side. At least, it’s available for the folks who have access to Apache (or their web server).
I was in great need for this. Flash 5 was the last hope, but I recently tried it with no results.
Kudos! Thanks!!!!
guy
One more question: Have you tried using .htaccess for the proxy rules? Having the rules in httpd.conf works fine for static stuff.
If we could use .htaccess, that’ll make things more dynamic and powerful.
I’ve tried a couple of rules – but none worked!
Let me know. Thanks.
Abhinav Singh
Nope i haven’t used .htaccess for such things till now.
[...] is combined with javascript hacks for streaming data from the custom http servers. Read “How to make cross-sub-domain ajax (XHR) requests using mod_proxy and iframes” for [...]