{"id":12292,"date":"2017-01-17T12:21:00","date_gmt":"2017-01-17T12:21:00","guid":{"rendered":"https:\/\/viewmyprojects.com\/winwirewp\/?p=12292"},"modified":"2023-11-05T14:10:49","modified_gmt":"2023-11-05T14:10:49","slug":"cross-domain-api-access-using-jquery-and-jsonp","status":"publish","type":"post","link":"https:\/\/viewmyprojects.com\/winwirewp\/blog\/cross-domain-api-access-using-jquery-and-jsonp\/","title":{"rendered":"Cross Domain API Access using JQuery and JSONP"},"content":{"rendered":"\n<p><strong>Overview<\/strong><\/p>\n\n\n\n<p>In today\u2019s web development, it is pretty common practice to load data using WebApi \/ Rest based service from Client side script (Jquery\/AngularJS). There is no issue when consumer web application and rest\/api services are hosted in the same domain, but when web-based applications are trying to load data from a domain which is not under your control, the chances are that you\u2019ve seen the following message in your browser\u2019s console:<\/p>\n\n\n\n<p>XMLHttpRequest cannot load http:\/\/external-domain\/service. No \u2018Access-Control-Allow-Origin\u2019 header is present on the requested resource. Origin \u2018http:\/\/my-domain\u2019 is therefore not allowed access.<\/p>\n\n\n\n<p><em>In this article, we\u2019ll look at what causes this error and how we can get around it by using jQuery and JSONP to make a cross-domain Ajax call.<br><\/em><br><strong>What is same origin policy?<br><\/strong><br>Browsers allow a web page to make AJAX requests only within the same domain. Browser security prevents a web page from making AJAX requests to another domain. This is called same origin policy.<\/p>\n\n\n\n<p>Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, however, they\u2019re often restricted in what they perform by the same-origin-policy. This is an important concept in the browser security model and controls that a web browser may only allow scripts on page A to access data on page B if these two pages have the same origin. The origin of a page is defined as a combination of URI Scheme, host name, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page.<\/p>\n\n\n\n<p><strong>The following 2 URLs have the same origin<br><\/strong><br>http:\/\/localhost: 59736\/api\/customers<br>http:\/\/localhost: 59736\/defualt.html<\/p>\n\n\n\n<p>The following 2 URLs have different origins because they have different port numbers (59736v\/s 59705)<br>http:\/\/localhost: 59736\/api\/customers<br>http:\/\/localhost: 59705\/default.html<\/p>\n\n\n\n<p>The following 2 URLs have different origins because they have different domains (.com v\/s .net)<br>http:\/\/Sampletech.com\/api\/Customers<br>http:\/\/Sampletech.net\/default.html<\/p>\n\n\n\n<p>The following 2 URLs have different origins because they have different schemes (http v\/s https)<br>https:\/\/Sampletech.com\/api\/customers<br>http:\/\/Sampletech.com\/default.html<\/p>\n\n\n\n<p>To prove browsers does not allow cross domain ajax requests, Lets\u2019s add simple web API which returns the All customer details.<br>Here is Code Snippet for Web Api:<br>Customer Model Class:<br>public class Customer<br>{<br>public int ID { get; set; }<br>public string FirstName { get; set; }<br>public string LastName { get; set; }<br>public string Phone { get; set; }<br>}<\/p>\n\n\n\n<p>Web Api Controller Class:<\/p>\n\n\n\n<p>namespace SampleWebApi.Controllers<br>{<br>[RoutePrefix(\u201capi\/Customer\u201d)]<br>public class CustomerController : ApiController<br>{<br>\/\/ GET api\/Customer<br>public IHttpActionResult Get()<br>{<br>List CustList = new List();<br>CustList.Add(new Customer() { ID = 1, FirstName = \u201cGILBERT\u201d, LastName = \u201cSMITH\u201d, Phone = \u201c408629-0589\u201d });<br>CustList.Add(new Customer() { ID = 2, FirstName = \u201cR\u201d, LastName = \u201cBATTERSBY\u201d, Phone = \u201c919\/489-6792\u201d });<br>CustList.Add(new Customer() { ID = 3, FirstName = \u201cLEONARD\u201d, LastName = \u201cDOS REMEDIOS\u201d, Phone = \u201c301\/760-2541\u201d });<br>CustList.Add(new Customer() { ID = 4, FirstName = \u201cITO\u201d, LastName = \u201cTAYLOR-HUNYADI\u201d, Phone = \u201c(02)933-3212\u201d });<br>CustList.Add(new Customer() { ID = 5, FirstName = \u201cSHIEKELESLAM\u201d, LastName = \u201cSHALA\u201d, Phone = \u201c03\/734-5111\u201d });<br>CustList.Add(new Customer() { ID = 6, FirstName = \u201cDUNNETT\u201d, LastName = \u201cCHRISTINE\u201d, Phone = \u201c(03)022-2332\u201d });<br>return Ok(CustList);<br>}<br>}<br>}<br>If we access above API from browser, the customer Api would return the all existing Customers.<br>API URL in my system is \u201chttp:\/\/localhost:59736\/api\/Customer\u201d<\/p>\n\n\n\n<p>Let\u2019s add a new client asp.net web project and adddefault.html Copy and paste the following HTML and jQuery code.<\/p>\n\n\n\n<p>$(document).ready(function () {<br>var ulCustomers= $(\u2018#ulCustomers\u2019);<\/p>\n\n\n\n<p>$(\u2018#btn\u2019).click(function () {<br>$.ajax({<br>type: \u2018GET\u2019,<br>\/\/ Make sure to change the port number to<br>\/\/ where you have the Customer service<br>\/\/ running on your local machine<br>url: \u2018http:\/\/localhost:59736\/api\/Customer\u2019,<br>dataType: \u2018json\u2019,<br>success: function (data) {<br>ulCustomers.empty();<br>$.each(data, function (index, val) {<br>var fullName = val.FirstName + \u2018 \u2018 + val.LastName;<br>ulCustomers.append(\u2018<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u2018 + fullName + \u2018<\/li>\n<\/ul>\n\n\n\n<p>\u2018)<br>});<br>}<br>});<br>});<\/p>\n\n\n\n<p>$(\u2018#btnClear\u2019).click(function () {<br>ulCustomers.empty();<br>});<br>});<\/p>\n\n\n\n<p>When you click \u201cGet All Customers\u201d button on \u201cdefault.html\u201d page, you get the following error. To see the error launch browser tools and click on the console tab.<br>XMLHttpRequest cannot load http:\/\/localhost:59736\/api\/Customer. No \u2018Access-Control-Allow-Origin\u2019 header is present on the requested resource. Origin \u2018http:\/\/localhost:59705\u2019 is therefore not allowed access<\/p>\n\n\n\n<p>On the other hand If API and client html page on same origin (same port) and click \u201cGet All Customers\u201d could have Customers data displayed without any problem. But in above scenario port number for client application and web api url is different, so as per the browser security policy is not allowing ajax to access different domain content.<\/p>\n\n\n\n<p>So this proves, browsers does not allow cross domain ajax requests. There are 2 ways to get around this problem<\/p>\n\n\n\n<p class=\"blog-detail-list\">\u2022 Using JSONP (JSON with Padding)<br>\u2022 Enabling CORS (Cross Origin Resource Sharing)<\/p>\n\n\n\n<p>CORS can be used as a modern alternative to the JSONP pattern. While JSONP supports only the GET request method, CORS also supports other types of HTTP requests. Using CORS enables a web programmer to use regular XMLHttpRequest, which supports better error handling than JSONP. On the other hand, JSONP works on legacy browsers which predate CORS support. CORS is supported by most modern web browsers. Also, while JSONP can cause cross-site scripting (XSS) issues where the external site is compromised, CORS allows websites to manually parse responses to ensure security.<\/p>\n\n\n\n<p><strong>In this blog, let\u2019s use JSONP to overcome the browser cross-domain restriction.<\/strong><\/p>\n\n\n\n<p>So what is JSONP and what does it do?<\/p>\n\n\n\n<p>JSONP (which stands for JSON with Padding) builds on this technique and provides us with a way to access the returned data. It does this by having the server return JSON data wrapped in a function call (the \u201cpadding\u201d) which can then be interpreted by the browser. This function must be defined in the page evaluating the JSONP response.<\/p>\n\n\n\n<p>JSONP stands for JSON with Padding. All JSONP does is wraps the data in a function. So for example, if you have the following JSON object.<\/p>\n\n\n\n<p>{<br>\u201cFirstName\u201d : \u201cSHIEKELESLAM\u201d,<br>\u201cLastName\u201d : \u201cSHALA\u201d,<br>\u201cPhone\u201d : \u201c502(734)-5111\u201d,<br>}<\/p>\n\n\n\n<p>JSONP will wrap the data in a function as shown below<br>CallbackFunction({<br>\u201cFirstName\u201d : \u201cSHIEKELESLAM\u201d,<br>\u201cLastName\u201d : \u201cSHALA\u201d,<br>\u201cPhone\u201d : \u201c502(734)-5111\u201d,<br>})<\/p>\n\n\n\n<p>The interesting fact that Browsers allow consuming JavaScript 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.<\/p>\n\n\n\n<p>Steps to make ASP.NET Web API Service to return JSONP formatted data and consume it from a cross domain ajax request.<\/p>\n\n\n\n<p><strong>Step 1<\/strong>: To support JSONP format, execute the following command using NuGet Package Manager Console which installs WebApiContrib.Formatting.Jsonp package.<br>Install-Package WebApiContrib.Formatting.Jsonp<\/p>\n\n\n\n<p><strong>Step 2<\/strong>: Include the following 3 lines of code in Application_Start () method of Global.asax.cs class<br>var config = GlobalConfiguration.Configuration;<br>var jsonpFormatter = new JsonpMediaTypeFormatter(config.Formatters.JsonFormatter);<br>config.Formatters.Insert(0, jsonpFormatter);<\/p>\n\n\n\n<p>Web API Global.asax.cs code snippet:<br>using WebApiContrib.Formatting.Jsonp;<\/p>\n\n\n\n<p>namespace SampleWebApi<br>{<br>public class WebApiApplication : System.Web.HttpApplication<br>{<br>protected void Application_Start()<br>{<br>AreaRegistration.RegisterAllAreas();<br>GlobalConfiguration.Configure(WebApiConfig.Register);<br>FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);<br>RouteConfig.RegisterRoutes(RouteTable.Routes);<br>BundleConfig.RegisterBundles(BundleTable.Bundles);<\/p>\n\n\n\n<p>var config = GlobalConfiguration.Configuration;<br>var jsonpFormatter = new JsonpMediaTypeFormatter(config.Formatters.JsonFormatter);<br>config.Formatters.Insert(0, jsonpFormatter);<br>}<br>}<br>}<\/p>\n\n\n\n<p><strong>Step 3:<\/strong>&nbsp;In the ClientApplication, set the dataType option of the jQuery ajax function to jsonp<br>dataType: \u2018jsonp\u2019<\/p>\n\n\n\n<p>After proceeding with above 3 steps, build the solution and access from browser must be populated Customer data on the Screen.<\/p>\n\n\n\n<p><strong>Conclusion<br><\/strong><br>JSONP enables users to avoid the same-origin policy and to some extent make cross-domain Ajax calls. It is simply not a silver bullet and it undeniably has its own issues as well; however, in some cases, it can prove helpful when you need to fetch data from a different origin.<br>JSONP also makes it possible to extract a variety of content from various services. Many leading sites provide JSONP services (for example Flickr), allows users to access its content via a predefined API.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Overview In today\u2019s web development, it is pretty common practice to load data using WebApi \/ Rest based service from Client side script (Jquery\/AngularJS). There is no issue when consumer web application and rest\/api services are hosted in the same domain, but when web-based applications are trying to load data from a domain which is&hellip; <a class=\"more-link\" href=\"https:\/\/viewmyprojects.com\/winwirewp\/blog\/cross-domain-api-access-using-jquery-and-jsonp\/\">Continue reading <span class=\"screen-reader-text\">Cross Domain API Access using JQuery and JSONP<\/span><\/a><\/p>\n","protected":false},"author":40,"featured_media":16695,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_eb_attr":"","_uag_custom_page_level_css":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-12292","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","entry"],"acf":[],"featured_image_src":"https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic.webp","author_info":{"display_name":"Naga","author_link":"https:\/\/viewmyprojects.com\/winwirewp\/author\/naga\/"},"views":3761,"uagb_featured_image_src":{"full":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic.webp",800,440,false],"thumbnail":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic-150x150.webp",150,150,true],"medium":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic-300x165.webp",300,165,true],"medium_large":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic-768x422.webp",750,412,true],"large":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic.webp",750,413,false],"1536x1536":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic.webp",800,440,false],"2048x2048":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic.webp",800,440,false],"post-thumbnail":["https:\/\/viewmyprojects.com\/winwirewp\/wp-content\/uploads\/2023\/11\/Cross-Domain-API-Access-using-JQuery-and-JSONP-graphic.webp",800,440,false]},"uagb_author_info":{"display_name":"Naga","author_link":"https:\/\/viewmyprojects.com\/winwirewp\/author\/naga\/"},"uagb_comment_info":0,"uagb_excerpt":"Overview In today\u2019s web development, it is pretty common practice to load data using WebApi \/ Rest based service from Client side script (Jquery\/AngularJS). There is no issue when consumer web application and rest\/api services are hosted in the same domain, but when web-based applications are trying to load data from a domain which is&hellip;&hellip;","_links":{"self":[{"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/posts\/12292","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/comments?post=12292"}],"version-history":[{"count":1,"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/posts\/12292\/revisions"}],"predecessor-version":[{"id":14268,"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/posts\/12292\/revisions\/14268"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/media\/16695"}],"wp:attachment":[{"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/media?parent=12292"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/categories?post=12292"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/viewmyprojects.com\/winwirewp\/wp-json\/wp\/v2\/tags?post=12292"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}