{"componentChunkName":"component---src-templates-tag-js","path":"/tags/jsonp/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"fields":{"slug":"/engineering/understanding-jsonp/"},"html":"<p>Nowadays, many API providers support JSONP requests. One reason for this is that most web browsers disable cross-domain requests when using basic Ajax.</p>\n<p>For example, if your website has the domain \"a.com\", it will use JavaScript hosted on a.com. When the a.com JavaScript makes an Ajax call to make a request on b.com, most web browsers would automatically deem the Ajax call as insecure and disable it. This is called the Same-Origin Policy and web browsers have this to prevent malicious scripts from sending off information to a different domain. Because you need the a.com JavaScript to access b.com to provide your service, this seems to pose a pretty big issue … JSONP to the rescue!</p>\n<p>Before understanding JSONP, we already know JSON is an object notation of JavaScript. The \"P\" stands for padding. So it’s a padded JSON, and, to be more specific, the JSON object is padded with a JavaScript function! It looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">jsFunction</span><span class=\"mtk1\">({</span><span class=\"mtk8\">&quot;name&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Ash Ketchum&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;role&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Pokemon trainer&quot;</span><span class=\"mtk1\">});</span></span></code></pre>\n<p>Thus, technically, any call that retrieves JSONP, sends off an executable JavaScript line, if and only if your page has a JavaScript function that has the same function name that’s returned in the JSONP!</p>\n<p>Let’s look at an example: say the user is on a.com and the browser is using JavaScript hosted on a.com. Then I shouldn't have any issues making Ajax calls to a.com. Ajax GET requests to b.com however, would fail. To avoid this, I first create a method in the JavaScript code that's located on a.com with the following signature</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getData</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// use this data</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>With this, an Ajax call using JSONP will pass through fine and return this data:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">getData</span><span class=\"mtk1\">({</span><span class=\"mtk8\">&quot;name&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;test&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;value&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;test Value&quot;</span><span class=\"mtk1\">});</span></span></code></pre>\n<p>After processing the request, the web browser will call the \"getData\" function because whenever a JavaScript tag is loaded, it gets executed.</p>\n<p>Now, the JSON object will get passed as an argument to the getData function as the data parameter. So, you can think of the getData as a callback method of the request.</p>\n<p>You can see the below code clearly</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addJavascriptFile</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">url</span><span class=\"mtk1\">, </span><span class=\"mtk12\">context</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">context</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">context</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">document</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">head</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementsByTagName</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;head&#39;</span><span class=\"mtk1\">)\\[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">\\];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">js</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createElement</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;script&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">js</span><span class=\"mtk1\">.</span><span class=\"mtk12\">src</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">url</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">js</span><span class=\"mtk1\">.</span><span class=\"mtk12\">type</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;text/JavaScript&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">head</span><span class=\"mtk1\">.</span><span class=\"mtk11\">appendChild</span><span class=\"mtk1\">(</span><span class=\"mtk12\">js</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">js</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getJsonp</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">url</span><span class=\"mtk1\">, </span><span class=\"mtk12\">handle</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//creating random name of function as to not conflict with others</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">func</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;jsonpCallback&#39;</span><span class=\"mtk1\"> + </span><span class=\"mtk10\">Math</span><span class=\"mtk1\">.</span><span class=\"mtk11\">floor</span><span class=\"mtk1\">((</span><span class=\"mtk10\">Math</span><span class=\"mtk1\">.</span><span class=\"mtk11\">random</span><span class=\"mtk1\">() \\* </span><span class=\"mtk7\">1000000000000000000</span><span class=\"mtk1\">) + </span><span class=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//adding randomly created function to global window object</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">window</span><span class=\"mtk1\">\\[</span><span class=\"mtk12\">func</span><span class=\"mtk1\">\\] = </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">data</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//calling handle</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">handle</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//removing random named declared function</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">window</span><span class=\"mtk1\">\\[</span><span class=\"mtk12\">func</span><span class=\"mtk1\">\\] = </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> () {};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//removing added js</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk12\">head</span><span class=\"mtk1\">.</span><span class=\"mtk11\">removeChild</span><span class=\"mtk1\">(</span><span class=\"mtk12\">js</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//manipulating and adding js file to head</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endurl</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">url</span><span class=\"mtk1\">.</span><span class=\"mtk11\">indexOf</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;?&#39;</span><span class=\"mtk1\">) != -</span><span class=\"mtk7\">1</span><span class=\"mtk1\"> ? </span><span class=\"mtk12\">url</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&#39;&amp;amp;callback=&#39;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">func</span><span class=\"mtk1\"> : </span><span class=\"mtk12\">url</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&#39;?callback=&#39;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">func</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">js</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">addJavascriptFile</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endurl</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The above code is not doing any magic, it will accept the URL of the API and add a parameter callback with a random name, and also create a global method with this same random name. It will then create a script tag and add the complete URL to src of this tag.</p>\n<p>The API will read the callback parameter from the query string and, if the callback parameter has the value \"jsonCallback\", the response will be as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">jsonpCallback</span><span class=\"mtk1\">({</span><span class=\"mtk8\">&quot;name&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;test&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;value&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;test Value&quot;</span><span class=\"mtk1\">});</span></span></code></pre>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"June 29, 2018","updated_date":null,"title":"Understanding JSONP","tags":["JavaScript","JSONP","API"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.834862385321101,"src":"/static/85e9390b35cfcd06b4e455bd05cc8ea7/50fff/Screenshot-2018-06-29-12.21.27.webp","srcSet":"/static/85e9390b35cfcd06b4e455bd05cc8ea7/61e93/Screenshot-2018-06-29-12.21.27.webp 200w,\n/static/85e9390b35cfcd06b4e455bd05cc8ea7/1f5c5/Screenshot-2018-06-29-12.21.27.webp 400w,\n/static/85e9390b35cfcd06b4e455bd05cc8ea7/50fff/Screenshot-2018-06-29-12.21.27.webp 730w","sizes":"(max-width: 730px) 100vw, 730px"}}},"author":{"id":"Rakesh Soni","github":"oyesoni","avatar":"rakesh-soni.webp"}}}}]}},"pageContext":{"tag":"JSONP"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}