In this article, I am going to discuss Calling Web API Service in a Cross-Domain Using jQuery AJAX. Please read our previous article before proceeding to this article where we discussed how to consume a Web API service using jQuery AJAX with an example.
What is the same-origin policy of a browser?
The browsers default behavior is that it allows a web page to make AJAX calls only within the same domain that means the browser security prevents a web page to make AJAX requests to other domains. This is called the same-origin policy.
The origin of a request consists of Scheme, Host and Port number. So, two requests are considered to be as the same origin if they have the same scheme, same host and same port number. If any of these differ, then the requests are considered to be cross-origin, i.e., not belonging to the same origins.
What do you mean by Cross-Domain?
Let us understand Cross-Domain with some examples.
The following 2 URLs have the same origin
http://localhost:1234/api/Employee/GetEmployees
http://localhost:1234/Home/Index
The following 2 URLs have different origins because they have different port numbers (1234 v/s 5678)
http://localhost:1234/api/Employee/GetEmployees
http://localhost:5678/Home/Index
The following 2 URLs have different origins because they have different domains (.com v/s .net)
http://example.com/api/Employee/GetEmployees
http://example.net/Home/Index
The following 2 URLs have different origins because they have different schemes (http v/s https)
https://example.com/api/Employee/GetEmployees
http://example.net/Home/Index
To prove browsers do not allow cross-domain AJAX calls, let’s create a new ASP.NET MVC application. Name it as MVCClient as shown below.
Open Visual Studio and create a new project
From the Visual Studio context menu, select File => New => Project as shown below
In the “New Project” window select “Visual C#” under the “Installed – Templates” and from the middle pane select the “ASP.NET Web Application” and name the project as “MVCClient” and then click on the “OK” button as shown in the below image
Once you click on the OK button, then a new popup window will open with Name New ASP.NET Project for selecting project Templates and from that window, we are going to select the MVC project template. Next, we need to select the Authentication type for doing that, we just click on Change Authentication button, a new dialog will pop up with the name “Change Authentication” here we are going to select No Authentication option and then click on the OK button as shown in the below image.
Once you click on the OK button, It will take some to time create the project for us.
Add an HTML page.
Right-click on the project then select Add => Html Page as shown below
Provide the Name as HtmlPage1.html and click on the Ok button as shown below.
Copy and paste the following HTML and jQuery code in HtmlPage1.html file.
Now first run the Service Project. Then run HtmlPage1.html file from the client project. When you click on the “Get All Employees” button on “HtmlPage1.html” page, you get the following error. To see the error launch browser tools and click on the console tab.
Failed to load http://localhost:53009/api/Employee/GetEmployees: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:62611’ is therefore not allowed access.
On the other hand, when you click on the “Get All Employees” button on “HtmlPage1.html” page that is present in the same project as the ASP.NET Web API Service, the employee data is displayed without any problem. So this proves, browsers do not allow cross-domain AJAX requests. There are 2 ways to get around this problem
What is JSONP and what does it do?
JSONP stands for JSON with Padding. The job of JSONP is to wraps the data into a function. For example, if you have the following JSON object
JSONP will wrap the data in a function as shown below
Browsers allow consuming JavaScript (JavaScript function) that is present in a different domain but not data. Since the data is wrapped in a JavaScript function, this can be consumed by a web page that is present in a different domain.
Steps to make ASP.NET Web API Service return JSONP formatted data and consume it from a cross-domain AJAX request
Step1: To support JSONP format, execute the following command using NuGet Package Manager Console which installs WebApiContrib.Formatting.Jsonp package.
Install-Package WebApiContrib.Formatting.Jsonp
Step2: Modify the Register() method of WebApiConfig class in WebApiConfig.cs file in App_Start folder of our web API project.
Step3: In the ClientApplication i.e. MVCClient project, set the dataType option of the jQuery ajax function to jsonp
Now run the service application first. Then run the client application and navigate to the URL “http://localhost:61757/HtmlPage1.html” and click on Get All Employees which will display all the employees’ information.
Summary:
I Hope this post will be helpful to understand hoow to call Web API services in a Cross-Domain using jQuery AJAX
Please share this post with your friends and colleagues.
For any queries please post a comment below.
Happy Coding 😉
What is the same-origin policy of a browser?
The browsers default behavior is that it allows a web page to make AJAX calls only within the same domain that means the browser security prevents a web page to make AJAX requests to other domains. This is called the same-origin policy.
The origin of a request consists of Scheme, Host and Port number. So, two requests are considered to be as the same origin if they have the same scheme, same host and same port number. If any of these differ, then the requests are considered to be cross-origin, i.e., not belonging to the same origins.
What do you mean by Cross-Domain?
Let us understand Cross-Domain with some examples.
The following 2 URLs have the same origin
http://localhost:1234/api/Employee/GetEmployees
http://localhost:1234/Home/Index
The following 2 URLs have different origins because they have different port numbers (1234 v/s 5678)
http://localhost:1234/api/Employee/GetEmployees
http://localhost:5678/Home/Index
The following 2 URLs have different origins because they have different domains (.com v/s .net)
http://example.com/api/Employee/GetEmployees
http://example.net/Home/Index
The following 2 URLs have different origins because they have different schemes (http v/s https)
https://example.com/api/Employee/GetEmployees
http://example.net/Home/Index
To prove browsers do not allow cross-domain AJAX calls, let’s create a new ASP.NET MVC application. Name it as MVCClient as shown below.
Open Visual Studio and create a new project
From the Visual Studio context menu, select File => New => Project as shown below
In the “New Project” window select “Visual C#” under the “Installed – Templates” and from the middle pane select the “ASP.NET Web Application” and name the project as “MVCClient” and then click on the “OK” button as shown in the below image
Once you click on the OK button, then a new popup window will open with Name New ASP.NET Project for selecting project Templates and from that window, we are going to select the MVC project template. Next, we need to select the Authentication type for doing that, we just click on Change Authentication button, a new dialog will pop up with the name “Change Authentication” here we are going to select No Authentication option and then click on the OK button as shown in the below image.
Once you click on the OK button, It will take some to time create the project for us.
Add an HTML page.
Right-click on the project then select Add => Html Page as shown below
Provide the Name as HtmlPage1.html and click on the Ok button as shown below.
Copy and paste the following HTML and jQuery code in HtmlPage1.html file.
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> <script src="Scripts/jquery-3.3.1.js"></script> <script type="text/javascript"> $(document).ready(function () { var ulEmployees = $('#ulEmployees'); $('#btnGetEmployees').click(function () { $.ajax({ type: 'GET', // Make sure to change the port number to // where you have the employee service // running on your local machine url: 'http://localhost:53009/api/Employees/GetEmployees', dataType: 'json', success: function (data) { ulEmployees.empty(); $.each(data, function (index, val) { ulEmployees.append('<li> First Name - ' + val.FirstName + " Last Name - " + val.LastName + " Gender- " + val.Gender + '</li>'); }); } }); }); $('#btnClear').click(function () { ulEmployees.empty(); }); }); </script> </head> <body> <div> <input id="btnGetEmployees" type="button" value="Get All Employees" /> <input id="btnClear" type="button" value="Clear" /> <ul id="ulEmployees" /> </div> </body> </html>
Now first run the Service Project. Then run HtmlPage1.html file from the client project. When you click on the “Get All Employees” button on “HtmlPage1.html” page, you get the following error. To see the error launch browser tools and click on the console tab.
Failed to load http://localhost:53009/api/Employee/GetEmployees: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:62611’ is therefore not allowed access.
On the other hand, when you click on the “Get All Employees” button on “HtmlPage1.html” page that is present in the same project as the ASP.NET Web API Service, the employee data is displayed without any problem. So this proves, browsers do not allow cross-domain AJAX requests. There are 2 ways to get around this problem
- Using JSONP (JSON with Padding)
- Enabling CORS (Cross-Origin Resource Sharing)
What is JSONP and what does it do?
JSONP stands for JSON with Padding. The job of JSONP is to wraps the data into a function. For example, if you have the following JSON object
{ “FirstName”: “Pranaya”, “LastName”: “Kumar”, “Gender”: “Male” }
JSONP will wrap the data in a function as shown below
CallbackFunction({ “FirstName”: “Pranaya”, “LastName”: “Kumar”, “Gender”: “Male”, })
Browsers allow consuming JavaScript (JavaScript function) that is present in a different domain but not data. Since the data is wrapped in a JavaScript function, this can be consumed by a web page that is present in a different domain.
Steps to make ASP.NET Web API Service return JSONP formatted data and consume it from a cross-domain AJAX request
Step1: To support JSONP format, execute the following command using NuGet Package Manager Console which installs WebApiContrib.Formatting.Jsonp package.
Install-Package WebApiContrib.Formatting.Jsonp
Step2: Modify the Register() method of WebApiConfig class in WebApiConfig.cs file in App_Start folder of our web API project.
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); var jsonpFormatter = new JsonpMediaTypeFormatter(config.Formatters.JsonFormatter); config.Formatters.Insert(0, jsonpFormatter); } }
Step3: In the ClientApplication i.e. MVCClient project, set the dataType option of the jQuery ajax function to jsonp
dataType: ‘jsonp’Complete Code:
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> <script src="Scripts/jquery-3.3.1.js"></script> <script type="text/javascript"> $(document).ready(function () { var ulEmployees = $('#ulEmployees'); $('#btnGetEmployees').click(function () { $.ajax({ type: 'GET', // Make sure to change the port number to // where you have the employee service // running on your local machine url: 'http://localhost:53009/api/Employees/GetEmployees', dataType: 'jsonP', success: function (data) { ulEmployees.empty(); $.each(data, function (index, val) { ulEmployees.append('<li> First Name - ' + val.FirstName + " Last Name - " + val.LastName + " Gender- " + val.Gender + '</li>'); }); } }); }); $('#btnClear').click(function () { ulEmployees.empty(); }); }); </script> </head> <body> <div> <input id="btnGetEmployees" type="button" value="Get All Employees" /> <input id="btnClear" type="button" value="Clear" /> <ul id="ulEmployees" /> </div> </body> </html>
Now run the service application first. Then run the client application and navigate to the URL “http://localhost:61757/HtmlPage1.html” and click on Get All Employees which will display all the employees’ information.
Summary:
I Hope this post will be helpful to understand hoow to call Web API services in a Cross-Domain using jQuery AJAX
Please share this post with your friends and colleagues.
For any queries please post a comment below.
Happy Coding 😉