Making Cross Domain AJAX calls from CRM Form JScript

One of the cool things about JScript in CRM 2011 is that you can now use the jQuery $.ajax method to call, most notably the CRM REST endpoint. Now, one of the things that is sometimes required in customers’ solution is the ability to call other REST endpoints from a CRM form. An example of that use case would be to have a button that calls a web service in order to perform some sort of operation (e.g. modify your current record, or just send data over another systems for synchronization etc.) in a synchronous and interactive way. Another example would be to automatically fill fields on a form with information coming from another system (retrieve them via web service and set the values on the form). There are two main issues with doing that :

  • First, some browsers will simply not allow jQuery AJAX requests to run if they are made to a domain different than that of the running web application. The reason behind is that not all browsers can create XMLHttpRequest objects that have a withCredentials property. That is used to specify that we want to include the user credentials in a cross domain request. To always have that working, jQuery has the solution for us. Use the following statement in the code before making the AJAX call: jQuery.support.cors = true;
  • The other more complicated issue is that most browsers simply won’t allow JavaScript to make a cross domain request for security reasons. In most contexts, this sounds normal and reasonable.

Here are a few workarounds if you are facing the second issue.

  1. Try to transfer your logic to the server side. Can you do what you need by using a dialog or a workflow with a custom activity (server side code)? Can your logic be performed on a synchronous plugin (server side code)? If one of these solutions is acceptable, then this is what you should do.Applies to: CRM Online, On Premise, ADFS / IFD
  2. Use IIS URL Rewrite rules on your server. To illustrate, let’s say your CRM server URL is http://MyCrmServer/MyOrg and your external REST endpoint is http://RestEndpoint/RestService?params. You can create a URL rewrite rule that will transform all requests coming in as http://MyCrmServer/RESTENDPOINT/RestService?params to http://RestEndpoint/RestService?params. In other words, whenever IIS sees the string MyCrmServer/RESTENDPOINT in a URL it replaces it with RestEndpoint. It is simple to configure with Regular Expressions.

    This is a good solution because it handles the request on the server side. From a Jscript perspective, it is as if you are querying the CRM server and the request is transformed once it reaches the server. You can read more about IIS URL Rewrite here. The downside of this approach is that every single page that is opened from the CRM web app triggers a URL rewrite rule evaluation. Microsoft says the algorithm are optimized for performance and I have never experienced visible delays due to using the rewriter. Also worth noting that obviously, this is not supported for CRM Online since we don’t have access to Microsoft’s CRM Servers.

    Applies to: CRM On Premise, ADFS / IFD (if provider gives access to CRM Server)

  3. Enable Cross Domain browsing on the browser. In IE, this is blocked by default. You can change the settings by going to Internet Options Security and Custom Level Settings. In most case, this solution is not acceptable for an enterprise’s perspective for security reasons.


    Applies to: CRM On Premise, ADFS / IFD, (CRM Online? Not confirmed but it should work)

I personally think making requests to a cross domain web site via JavaScript should not be done if there are acceptable other options simply because it adds overhead somewhere based on the solution you go with. (e.g. if you go with solution 2 on premises, you have to make sure all your CRM servers have rewrite rules create and enable etc.).

[*** Update | 13/06/2014 ***] If you are using CRM 2013, see this article on how to use Action processes to get around this challenge.

Hope this helps!