Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Cross Site Scripting...

5.00/5 (1 vote)
10 Mar 2011CC (ASA 2.5) 10.8K  
An easy way to do an AJAX call to another domain

Have you ever absolutely needed to do an AJAX call to another domain? Here is a way to do it (non-secure). Basically, we create a new IHttpHandler that listens for a request. It takes a single QueryString parameter, "url". It then passes the request on to the given destination. It supports all HTTP Methods (GET, PUT, HEAD, POST, etc.).

First, create a new class that implements IHttpHandler as follows:

CrossDomainHandler.ashx.cs
C#
using System;
using System.Globalization;
using System.IO;
using System.Net;
using System.Web;

namespace CrossDomain
{
 public class CrossDomainHandler : IHttpHandler
 {
  public CrossDomainHandler()
  {
  }

  public void ProcessRequest(HttpContext context)
  {
   try
   {
    string url = context.Request.QueryString["url"];

    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

    request.Headers.Clear();

    foreach (string key in context.Request.Headers.AllKeys)
    {
     string value = context.Request.Headers[key];

     if (string.Compare(key, "Connection", true, CultureInfo.InvariantCulture) == 0)
     {
      if (string.Compare(value, "Keep-Alive", true, CultureInfo.InvariantCulture) == 0)
      {
       request.KeepAlive = true;
      }
      else if (string.Compare(value, "Close", true, 
               CultureInfo.InvariantCulture) == 0)
      {
       request.KeepAlive = false;
      }
      else
      {
       request.Connection = value;
      }
     }
     else if (string.Compare(key, "Content-Length", true, 
                             CultureInfo.InvariantCulture) == 0)
     {
      int length = Convert.ToInt32(value);

      if (length > 0)
      {
       request.ContentLength = length;
      }
     }
     else if (string.Compare(key, "Accept", true, 
              CultureInfo.InvariantCulture) == 0)
     {
      request.Accept = value;
     }
     else if (string.Compare(key, "Content-Type", true, 
              CultureInfo.InvariantCulture) == 0)
     {
      request.ContentType = value;
     }
     else if (string.Compare(key, "Date", true, 
              CultureInfo.InvariantCulture) == 0)
     {
     }
     else if (string.Compare(key, "Expect", true, 
              CultureInfo.InvariantCulture) == 0)
     {
      request.Expect = value;
     }
     else if (string.Compare(key, "Host", true, 
              CultureInfo.InvariantCulture) == 0)
     {
     }
     else if (string.Compare(key, "If-Modified-Since", 
              true, CultureInfo.InvariantCulture) == 0)
     {
      request.IfModifiedSince = DateTime.Parse(value);
     }
     else if (string.Compare(key, "Proxy-Connection", true, 
              CultureInfo.InvariantCulture) == 0)
     {
     }
     else if (string.Compare(key, "Range", true, 
              CultureInfo.InvariantCulture) == 0)
     {
     }
     else if (string.Compare(key, "Referer", true, 
              CultureInfo.InvariantCulture) == 0)
     {
      request.Referer = value;
     }
     else if (string.Compare(key, "Transfer-Encoding", true, 
              CultureInfo.InvariantCulture) == 0)
     {
      request.TransferEncoding = value;
     }
     else if (string.Compare(key, "User-Agent", true, 
              CultureInfo.InvariantCulture) == 0)
     {
      request.UserAgent = value;
     }
     else
     {
      request.Headers.Add(key, value);
     }
    }

    request.Method = context.Request.HttpMethod;

    if (context.Request.ContentLength > 0)
    {
     CopyStream(context.Request.InputStream, 
                request.GetRequestStream(), 512);
    }

    using (HttpWebResponse response = 
          request.GetResponse() as HttpWebResponse)
    {
     context.Response.ClearHeaders();
     context.Response.ClearContent();

     foreach (string key in response.Headers.AllKeys)
     {
      context.Response.AddHeader(key, response.Headers[key]);
     }

     if (response.ContentLength > 0)
     {
      CopyStream(response.GetResponseStream(), 
                 context.Response.OutputStream, 512);
     }
    }
   }
   catch (Exception ex)
   {
    context.Response.Write(ex);
   }
  }

  public bool IsReusable
  {
   get
   {
    return false;
   }
  }

  private static void CopyStream(Stream input, 
          Stream output, int bufferSize)
  {
   byte[] buffer = new byte[bufferSize];
   int count = 0;

   while ((count = input.Read(buffer, 0, buffer.Length)) > 0)
   {
    output.Write(buffer, 0, count);
   }
  }

 }
}
CrossDomainHandler.ashx
ASP.NET
<%@ WebHandler Class="CrossDomain.CrossDomainHandler,CrossDomain" %>

Use it as follows:

C#
if (typeof XMLHttpRequest == "undefined") XMLHttpRequest = function() {
  try { return new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP") } catch(e) {}
  try { return new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
  throw new Error("This browser does not support XMLHttpRequest.")
};

var req = new XMLHttpRequest();

req.open('GET', 'CrossDomainHandler.ashx?url=http%3A%2F%2Fwww.google.com%2F', false);

alert(req.responseText);

Or, extend the Prototype JS Framework:

CrossDomainAjax.js
JavaScript
Ajax.CrossDomainRequest = Class.create(Ajax.Request, {
 initialize: function($super, url, handlerUrl, options) {
  this.handlerUrl = handlerUrl;
  $super(url, options);
 },
 request: function($super, url) {
  this.url = url;
  if (!this.isSameOrigin())
   url = this.handlerUrl + '?url=' + encodeURIComponent(url);
  $super(url);
 }
});

To use:

JavaScript
<script type="text/javascript">
var mine = new Ajax.CrossDomainRequest('http://www.google.com/', 
                                       'CrossDomainHandler.ashx', {
 method: 'head',
 onSuccess: function(transport) {
  $('mine').value = transport.getAllResponseHeaders();
 }
});
</script>

Hope this helps…

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-ShareAlike 2.5 License