A common solution to the XMLHttpRequest cross-domain issue (aka cross site scripting or XSS), where you can only communicate with the originating domain, is to configure Apache to use either
mod_proxy
or
mod_rewrite
for URL rewriting and a pass-through proxy.
With Apache you need to enable the proxy functions (
configure --enable-proxy
). If you want to handle it all with
mod_proxy
, then define you proxy settings in
httpd.conf
such as:
ProxyPass /doExt http://external.com/doAction
ProxyPassReverse /doExt http://external.com/doAction
If you want to use
mod_rewrite
then turn on
mod_rewrite
in
httpd.conf
or
.htaccess
with
RewriteEngine on
and define your rewriting rules such as:
RewriteRule ^/doExt$ http://external.com/doAction [P]
Then when you post to your server via /doExt, Apache will pass the request on to the external site.
That's all well and good if you have access to the Apache configuration or the server is already configured with the proper modules. But, when your on a hosted environment, that's not always feasible. Another solution would be to provide a proxy servlet to make the remote request for you and return the result. What I am providing is in Java and PHP, but it could be written you language of choice.
Java proxy
The following servlet class will invoke some external URL on behalf of the original request and return the result from the external request as the result of the original local request. Note: In the following code I hard-coded the real destination. However, it could be determined from a parameter in the original request just as easily.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Enumeration;
/**
* This is a simply proxy class in order to bypass AJAX security contraints.
*
*/
public class ServerProxy extends javax.servlet.http.HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException {
performTask(request, response);
}
public void doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException {
performTask(request, response);
}
public void performTask(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException {
// Get the external URL to invoke
String realUrl = "http://www.external.com";
// Copy the request parameters from the original request
Enumeration paramNames = request.getParameterNames();
String paramName;
while (paramNames.hasMoreElements()) {
paramName = (String) paramNames.nextElement();
realUrl = realUrl.concat(paramName + "="
+ request.getParameter(paramName));
if (paramNames.hasMoreElements()) {
realUrl = realUrl.concat("&");
}
}
// real URL will be returning XML data
response.setContentType("text/xml");
PrintWriter out = response.getWriter();
// invoke the real URL and copy the result into the response
// for the original request
URL real = new URL(realUrl);
BufferedReader in = new BufferedReader(
new InputStreamReader(real.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
out.println(inputLine);
in.close();
return;
}
}
PHP proxy
Here is a similar solution using PHP:
$remoteServer = "http://www.external.com";
$path = $_GET[”path”];
$proxyTarget = $remoteServer.$path;
$connection = curl_init($proxyTarget);
curl_setopt($connection, CURLOPT_HEADER, false);
curl_setopt($connection, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($connection);
curl_close($connection);
header(”Content-Type: text/xml”);
echo $data;