If you’ve read my post on Internet Explorer 8 and cross-domain requests [HERE] then you know that Internet Explorer 8 implements a new object called XDomainRequest. For this post I put together a little sample using HTTP GET and a WCF web service. To contrast the XMLHttpRequest object and the new XDomainRequest object I’ll send two requests, both of which will not validate as the same origin, the XMLHttpRequest object throws an exception, however the XDomainRequest object works as expected.

Checkout the small web service:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service
{
    // Add [WebGet] attribute to use HTTP GET
    [OperationContract]
    [WebGet]
    public string DoWork(string a)
    {
        WebOperationContext.Current.OutgoingResponse.Headers.Add("XDomainRequestAllowed:1");

        switch (a.ToLower())
        {
            case "hello":
                return "Hello! I'm a WCF web service responding an XDR";
                break;
            default:
                return "I don't know what to say :(";
                break;
        }

        return null;
    }
}

We can invoke the web service using both the XMLHttpRequest and XDomainRequest objects as shown below.

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <script type="text/javascript">
   1:  
   2:         function sendXdr()
   3:         {
   4:             // 1. Create XDR object
   5:             xdr = new XDomainRequest();
   6:  
   7:             // 2. Open connection with server using POST method.
   8:             xdr.open("GET", "http://127.0.0.1:53744/IE_XDR/Service.svc/DoWork?a=hello")
   9:  
  10:             // 3. Send string data to server. 
  11:             xdr.send();
  12:         }
  13:         
  14:         // XMLHttpRequest
  15:         function createXMLHttpObj()
  16:         {
  17:             var xmlHttpObj = null;
  18:             if (window.XMLHttpRequest)
  19:                 xmlHttpObj = new XMLHttpRequest();
  20:             else
  21:             {
  22:                 try
  23:                 {
  24:                     xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP");
  25:                 } 
  26:                 catch (e)
  27:                 {
  28:                     xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP");
  29:                 }
  30:             }
  31:             
  32:             if (xmlHttpObj)
  33:                 return xmlHttpObj;
  34:             else
  35:                 return null;
  36:         }
  37:         
  38:         function sendXmlHttpRequest()
  39:         {
  40:             var xmlHttpObj = createXMLHttpObj();
  41:             if (!xmlHttpObj)
  42:                 return;
  43:             
  44:             try
  45:             {
  46:                 xmlHttpObj.open("GET", "http://127.0.0.1:53744/IE_XDR/Service.svc/DoWork?a=hello", true);
  47:                 xmlHttpObj.send();
  48:             }
  49:             catch(e)
  50:             {
  51:                 alert("Cross-site origin error.");
  52:             }
  53:         }
  54:     
</script> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager runat="server" ID="ScriptManager1"></asp:ScriptManager> <input type="button" value="Use XDomainRequest" onclick="javascript:sendXdr();" /> <br /> <input type="button" value="Use XMLHttpRequest" onclick="javascript:sendXmlHttpRequest();" /> </div> </form> </body> </html>

First and foremost, notice that the URL points to the IP address, however the original request made in my web browser is to the hostname, that is, localhost. As far as the web browser is concerned, the GET request for the XMLHttpRequest object (line 46 above) is not to the same origin as the requesting page, as the web browser validates the origin using string literals and localhost does not equal 127.0.0.1. Finally, when the XDomainRequest object is used to query the web service our response is returned as JSON text and is shown below:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Date: Wed, 16 Apr 2008 02:57:46 GMT
X-AspNet-Version: 2.0.50727
XDomainRequestAllowed: 1
Cache-Control: private
Content-Type: application/json; charset=utf-8
Content-Length: 54
Connection: Close

{"d":"Hello! I'm a WCF web service responding an XDR"}

However, when the XMLHttpRequest object is used the try/catch block catches the exception and the alert box is displayed:

image

There really isn't much more to it. In the future we can make use of the XDomainRequest object to query remote web services rather than constructing a web service proxy. For more details check out the MSDN documentation on the object [HERE].