Making cross-sub-domain ajax (XHR) requests using mod_proxy and iframes

Standard

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:

  1. Enable mod_proxy module.
    $ a2enmod proxy
    $ a2enmod proxy_http
    $ a2enmod proxy_connect
  2. 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
  3. 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!

  • http://excellencetechnologies.in manish

    Hey,

    I think we can make cross domain ajax request using jsonp.

    http://docs.jquery.com/Release:jQuery_1.2/Ajax

  • http://abhinavsingh.com Abhinav Singh

    Yup right, thats why the title reads “using mod_proxy and iframes” :D

    • http://excellencetechnologies.in 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?

    • http://abhinavsingh.com 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.

    • http://excellencetechnologies.in 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).

    • http://excellencetechnologies.in manish

      Any ways thanks for post, got to know news ways for cross domain ajax.

    • http://abhinavsingh.com 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.

    • http://abhinavsingh.com 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.

    • http://abhinavsingh.com Abhinav Singh

      Nope i haven’t used .htaccess for such things till now.

    • guy

      Howdy,

      One more question for you: I’ve successfully set up mox_proxy (reverse proxy) locally. I can make external ajax calls in Firefox & Safari with no problem. But I still get the Access Denied error from IE. Do you think it has to do with running things locally?

      Your proxy ajax demo works fine for me in IE. Yet, mine won’t work in IE.

      I’m thinking it might have to do with running it locally, but I’m not sure.

      Thanks.

    • http://abhinavsingh.com Abhinav Singh

      Hi,

      I remember testing this out locally before blogging and using it. So i don’t think running locally shd be an issue.

  • Pingback: How to build a custom static file serving HTTP server using Libevent in C | Abhi's Weblog()

  • MR Harrison

    hi man!

    thanks for the manual!
    Saved my live!

  • Pingback: Cross Domain Ajax Handler Using PHP » Swiftwater Solutions LLC()

  • bhavishya

    will the first approach (mod_proxy) will fulfill my probelme .my problem is” i want to integrate my application with other web site .in this my web site will send post request to some other web site on behalf of the user so this will set cookies in user browser than it will redirect user to that site so user does not need to provide authentication detail again”.

  • rahul

    please tell methat how can do cross sub domian ajax in asp.net please remember that i am begginer so tell me more clarly