In this blog, I am going to explain how to solve CORS in Salesforce by using JSONP( JSON Padding )
What is CORS?
CORS introduces a standard mechanism that can be used by all browsers for implementing cross-domain requests. The spec defines a set of headers that allow the browser and server to communicate about which requests are (and are not) allowed.Cross-Origin Resource Sharing (CORS) allows us to use Web applications within browsers when domains aren’t the same. For example, a site with domain wants to execute x.org AJAX requests to a Web application with the domain y.org using HTTP.
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using or XMLHttpRequest Fetch could only make HTTP requests to its own domain.
The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. Additionally, for HTTP request methods that can cause side-effects on server’s data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers “preflight” the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon “approval” from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether “credentials” (including Cookies and HTTP Authentication data) should be sent with requests.
What is JSONP?
JSONP is JSON Padding is technology that enables Sharing of data bypassing Same-origin policy. The policy disallows running JavaScript to read media DOM elements or XHR data fetched from outside the page’s origin In JSONP a server must reply with a response that includes the JSONP function. JSONP does not work with JSON-formatted results. The JSONP function invocation that gets sent back, and the payload that the function receives, must be agreed upon by the client and server.
For Examples in this script, parseResponse is the function which will return as part of the script invocation
http://server.example.com/Users/1234?callback=parseResponse
In this example, the received payload would be: parseResponse({“Name”: “Foo”, “Id”: 1234, “Rank”: 7}); because Javascript called via the tagscript
isn’t subject to the browser’s same-origin policy, the response will simply be executed in the browser with our parseResponse function.
Breaking it all down
The core elements of JSONP, then, are as such:
- A callback function defined on your site.
- A request to the remote API via
<script>
tag:- Includes a special param providing the name of your callback function
- The response:
- Is just Javascript
- That consists of:
- A function call, the name of which you specified in the request
- With the argument being the JSON data of interest
- Gets executed immediately, as if it were called from your own domain
Let’s test now:-
Create a visualforce page with the following code.
<apex:page showHeader="false" standardStylesheets="false"> https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js <script type = "text/javascript" language = "javascript"> $(document).ready(function() { $("#btn").click(function(event){ $.getJSON('https://api.flickr.com/services/feeds/photos_public.gne?tags=monkey&tagmode=any&format=json', function(jd) { $('#stage').html('<p> Name: ' + jd.description + '</p>'); }); }); }); </script> <body> <p>Simple JSON File to show the Demo .</p> <div id = "stage" style = "background-color:#cc0;"> Data Will be loaded </div> <input type = "button" id = "btn" value = "Load Data" /> </body> </apex:page>
Now after loading the page, go to console you will see an error message as shown below.
Now Replace the above code with the below code which is having JSONP logic
<apex:page showHeader="false" standardStylesheets="false"> https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js <script type = "text/javascript" language = "javascript"> $(document).ready(function() { $("#btn").click(function(event){ var script=document.createElement('script'); script.type='text/javascript'; script.src='https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=processJSON&tags=monkey&tagmode=any&format=json'; $("body").append(script); }); }); var processJSON = function (json) { console.log('json'+json); for (var item in json.items) { $('#stage').html(item); } }; </script> <body> <div id = "stage" style = "background-color:#cc0;"> Data Will be loaded </div> <input type = "button" id = "btn" value = "Load Data" /> </body> </apex:page>
Now if you can go and see the console, you will not see any error message.