views:

1063

answers:

3

I'm trying to decide whether to use a custom ASP.Net Ajax Extender or jQuery to perform a simple web service call. The web service method accepts a customer ID and returns the customer name. I'm leaning towards jQuery because of it's simplicity. The only problem is that due to my company's IE7 Group Policy settings, the first time jQuery invokes a web service it prompts the user with the following message:

A script is accessing some software (an ActiveX control) on this page which has been marked safe for scripting. Do you want to allow this?

The Extender does not cause this message to be displayed. I'm assuming the ASP.Net Ajax library has some javascript voodoo that suppresses it. So my questions is, How do I suppress this message using javascript?

Here's my aspx markup:

<h1>
    Finder Test</h1>
<div>
    <h2>
        Extender</h2>
    Customer ID:
    <asp:TextBox ID="txtCustomerId" runat="server" MaxLength="9" Width="4em" />
    <belCommon:FinderExtender ID="extCustomerId" runat="server" TargetControlID="txtCustomerId"
        ResultLabelID="lblResult" ServicePath="~/Customer.asmx" ServiceMethod="Name" />
    <asp:Label ID="lblResult" runat="server" />
</div>
<div>
    <h2>
        jQuery</h2>
    Customer ID:
    <input id="txtCustomerId2" type="text" maxlength="9" style="width: 4em;" value="0000" />
    <span id="txtCustomerName2"></span>

    <script type="text/javascript">
        $(document).ready(function()
        {
            $("#txtCustomerId2").change(
            function()
            {
                updateCustomerDescription(this.value, "txtCustomerName2");
            }).change();
        });

        function updateCustomerDescription(id, descriptionControlId)
        {
            // if we don't have a value, then don't bother calling the web service
            if (id == null || id.length == 0)
            {
                $("#" + descriptionControlId).text("");
                return;
            }

            jsonAjax("customer.asmx/Name", "{'id':'" + id + "'}", true,
                function(result)
                {
                    var name = result.d == null ? "" : result.d;
                    $("#" + descriptionControlId).text(name);
                }, null);
        }

        function jsonAjax(url, data, async, onSuccess, onFailed)
        {
            $.ajax({
                async: async,
                type: "POST",
                url: url,
                data: data,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: onSuccess,
                error: onFailed
            });
        }
    </script>
</div>

[Update]

I'm assuming that the ActiveX control referenced in the message is XMLHttpRequest. I'm also assuming that the internals of jQuery and ASP.Net Ajax both use it for IE7.

[Update]

The difference appears to be in how ASP.Net Ajax and jQuery construct an instance of XMLHttpRequest.

ASP.Net Ajax (thanks @Jesse Dearing):

 window.XMLHttpRequest = function window$XMLHttpRequest() {
 var progIDs = [ 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP' ];
 for (var i = 0, l = progIDs.length; i < l; i++) {
  try {
    return new ActiveXObject(progIDs[i]);
  }
  catch (ex) { }
  }
     return null;
  }
}

jQuery 1.3.2:

// Create the request object; Microsoft failed to properly
// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
// This function can be overriden by calling jQuery.ajaxSetup
xhr:function(){
    return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
}
+2  A: 

This doesn't sound right to me. If there is a security policy in place, you should not be able to override it with javascript.

I would double check the two pages and see if they both really access the same ActiveX control. I assume that the pages are coming from the same host (so there's no issue of different WinInet trust zones).

jdigital
Both the ASP.Net Ajax and the jQuery implementations are on the same page, and only the jQuery method causes the message. I'm pretty sure both implementations use an XMLHttpRequest ActiveX object.
jrummell
I'd look at the page source rather than making an assumption.
jdigital
+1  A: 

I'm working on an ASP.NET AJAX app so I checked the source of it and I found this in the ASP.NET AJAX code:

 window.XMLHttpRequest = function window$XMLHttpRequest() {
 var progIDs = [ 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP' ];
 for (var i = 0, l = progIDs.length; i < l; i++) {
  try {
    return new ActiveXObject(progIDs[i]);
  }
  catch (ex) { }
  }
     return null;
  }
}

I hope that helps some.

Jesse Dearing
Man, they do not even follow their own advice on what to use for the ids. :) http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
epascarello
+1  A: 

I solved this by overriding jQuery's xhr function as so:

function overrideJqueryXhr()
{
    $.ajaxSetup({
     xhr: function()
     {
      if (window.XMLHttpRequest)
      {
       return new XMLHttpRequest();
      }
      else
      {
       var progIDs = ['Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];

       for (var i = 0; i < progIDs.length; i++)
       {
        try
        {
         var xmlHttp = new ActiveXObject(progIDs[i]);
         return xmlHttp;
        }
        catch (ex)
        {
        }
       }

       return null;
      }
     }
    });
}

This function tells jQuery to create an instance of the XMLHttpRequest class for non-IE browsers, and then creates an ActiveX object the MS Ajax way for IE. It tries the latest version first, Msxml2.XMLHTTP.3.0, then Msxml2.XMLHTTP and finally Microsoft.XMLHTTP.

jrummell