cross-domain AJAX with PHP Proxies

You know the drill, you have this neat little web app you've been working on and the client says:

Hey, how about you include this weather service I found, you can use a web service right? It's just XML right?

Initially you think yeah, sure, not a problem. I'll just break out my trusty XMLHttpRequest() object and fire off a request, get the XML data back and populate my div tags on the fly. You sit down, write some code and... nothing happens.

A little (or perhaps a lot) of debugging later and you realise that the http request code you're firing off from the browser is returning nothing or, at best, a cryptic error message. And then it hits you. Your site is on this domain, that web service comes from a different domain and the browser's security model thinks you're up to no good.

Short of going back to the client and telling him his dream of being able to see what the weather is like in Murmansk (cold usually) from the comfort of his employee intranet portal is not going to be a reality, there is a solution. Using a little proxy script you can effectively mask the request to the external server so that the browser sees the request as going to the same domain that the web page was sourced from.

Proxy scripts are small, lightweight and barely add to response times (which is fine if your other alternative is a response time of well, never). The code below is for a specific example, but it is possible to write one to take any request and pass it on to the appropriate external service provider. The code below is in PHP but any server-side code will do.

phpProxy.php

  <?php
  /**
   * @author Gabriel Buckley
   * @copyright 2008
   */
  		
    $ch = curl_init("http://some.otherdomain.com/getUserDetails.xql");
    $strUser = $_POST["username"];
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt ($ch, CURLOPT_POSTFIELDS,"username=".urlencode($strUser));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);      
    curl_close($ch);
    echo $output
  ?>
        

All we're doing is recieving one URL parameter username and making a request to another server with the supplied parameter. Once that server replies back with its response, we simply echo the response straight back to the client. So nine lines of code to solve one of the most vexing problems web application developers need to contend with. It works by on one hand, using the server as a client to fetch the required data. Then allowing the same process to act in place of the proxied web function call by echoing exactly the same data which satisfies the browser securtiy model's requirement that requests be submitted only back to the originating domain.

Gabriel J. Buckley's Facebook profile
My status