By James Hibbard

jQuery’s JSONP Explained with Examples

By James Hibbard

This popular article was updated on 23rd June, 2016 to address quality issues. Comments pertaining to the old article were removed.

If you’re developing a web-based application and are trying to load data from a domain which is not under your control, the chances are that you’ve seen the following message in your browser’s console:

XMLHttpRequest cannot load http://external-domain/service. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://my-domain’ is therefore not allowed access.

In this article, we’ll 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.

Same-origin Policy

Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, however they’re restricted in what they can do by the same origin-policy. This is an important concept in the browser security model and dictates 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 by its protocol, host and port number. For example the origin of this page is ‘https’, ‘’, ’80’.

The same-origin policy is a saftey mechanism. It prevents scripts from reading data from your domain and sending it to their servers. If we didn’t have this, it would be easy for a malicious website to grab your session information to another site (such as Gmail or Twitter) and execute actions on your behalf. Unfortunately, it also causes the error we see above and often poses a headache for developers trying to accomplish a legitimate task.

A failing example

Let’s look at what doesn’t work. Here’s a JSON file residing on a different domain which we would like to load using jQuery’s getJSON method.

  function(json) { console.log(json); }

If you try that out in your browser with an open console, you will see a message similar to the one above. So what can we do?

A Possible Workaround

Luckily, not everything is affected by the same-origin policy. For example, it is quite possible to load an image or a script from a different domain into your page—this is exactly what you are doing when you include jQuery (for example) from a CDN.

This means that we are able to create a <script> tag, set the src attribute to that of our JSON file and inject it into the page.

var script = $("<script />", {
    src: "",
    type: "application/json"


Although that works, it doesn’t help us much, as we have no way of getting at the data it contains.


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 “padding”) which can then be interpreted by the browser. This function must be defined in the page evaluating the JSONP response.

Let’s see what that would look like with our previous example. Here’s an updated JSON file which wraps the original JSON data in a jsonCallback function.

function jsonCallback(json){

  url: "",
  dataType: "jsonp"

This logs the expected result to the console. We now have (albeit rather limited) cross-domain Ajax.


3rd Party APIs

Some 3rd party APIs let you specify a name for the callback function which should be executed when the request returns. One such API is the GitHub API.

In the following example we’re getting the user information for John Resig (jQuery creator) and using a logResults callback function to log the response to the console.

function logResults(json){

  url: "",
  dataType: "jsonp",
  jsonpCallback: "logResults"

This can also be written as:


The ? on the end of the URL tells jQuery that it’s dealing with a JSONP request instead of JSON. jQuery then automatically registers the callback function which it calls when the request retruns.

If you’d like to learn more about jQuery’s getJSON method, check out: Ajax/jQuery.getJSON Simple Example


But as you might have realized by now, there are some drawbacks to this approach.

For example, JSONP can only perform cross-domain GET requests and the server must explicitly support it. JSONP is also not without its security concerns, so let’s briefly look at some other solutions.

Using a proxy

Server-side code is not bound by the same origin policy and can perform cross-origin requests without a problem. You could therefore make some kind of proxy and use that to retrieve whatever data you need. With reference to our first example:

/* proxy.php */
$url = "";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec ($ch);
curl_close ($ch);
echo $result;

And on the client side:

$.getJSON("", function(json) {

But this approach also has its downsides. For example, if the third-party site uses cookies for authentication, this will not work.


Cross-Origin Resource Sharing (CORS) is a W3C spec to allow cross-domain communication from the browser. This is done by including a new Access-Control-Allow-Origin HTTP header in the response.

With reference to our first example, you could add the following to a .htaccess file (assumes Apache) to permit requests from a different origins:

Header add Access-Control-Allow-Origin ""

(If you have a server running something other than Apache, look here:

You can find out more about CORS in one of our recent tutorials: An In-depth Look at CORS


JSONP allows you to sidestep the same-origin policy and to some extent make cross-domain Ajax calls. It’s not a silver bullet, and it certainly has its issues, but in some cases it can prove invaluable when fetching data from a different origin.

JSONP also makes it possible to pull in a variety of content from different services. Many prominent sites provide JSONP services (for example Flickr), allowing you access to their content via a predefined API. You can find a comprehensive list of them in the ProgrammableWeb API directory.

  • Dickwan

    Many thanks for the quick and clean tips sir!

  • Pingback: Useful jQuery Function Demos For Your Projects | Layout to HTML()

  • Pingback: Useful jQuery Function Demos For Your Projects()

  • So the only way yo make a jsonp request is having access to the json file… and what if you can’t change the json file and it comes to you simply in this way: {“category”: “one”,”category”:”two”} etc… ?

    • Then you cannot call it cross domain unless you have a proxy pass setup or such.

  • Pingback: Problematiche cross-domain e jsonp | Blog su web design & development()

  • lifesaver!

  • zorg

    thanks, the jquery docs are abysmal on this

  • aaa


  • Dom

    After two days.. I reached this site..and it just worked out like mentioned here. Thanks a ton for the tips.

  • me

    Unsafe JavaScript attempt to access frame with URL :(

  • Pingback: 50 jQuery Function Demos for Aspiring Web Developers - Smashing Coding()

  • Leonardo

    – According to the JQuery API “jsonp requests do not support synchronous operation”. So what about that async: false?
    – In the first example, if you are specifying the “jsonpCallback” parameters within the $.ajax() call I guess you don’t need to append “?callback=?” parameter in the url, am I right?

  • this was very helpful, thanks a lot

  • Muhairwa Jean

    Intresting ..

  • John Schaap

    Yes I’ve been there one 2 many times. Thank you so much much for simplifying this process. :)

  • Just me

    Hi Sam,

    Thanks a lot for these code examples. I spend about half a day but with no result. When I read you article I understood how to use jsonp. Thanks!

  • Pingback: Caricamenti cross-domain con jsonp e jQuery |()

  • Pingback: Useful jQuery Function Demos For Your Projects - Internet Business()

  • omar salem

    simply doesn’t work

    • Diego

      The function callback already has the results ??? I didn’t understand.. Even if that’s a function..
      There is no clarity..
      I was looking for a REQUEST and a function to receive the response.. but the function here already has some code and the code is already there? … sorry, I didnt understand..

  • lse

    jsonp must run always on load of page …? or can run on press of a button?

    • dwsturgeon

      I’ve seen people tie Ajax request with carousels and click functions. Make sure your callback is unique

  • SGW

    Terribly written, no clue what’s going on

  • Alex

    Thanks, worked like a charm!

  • Chris Delaney

    Thanks so much. I was very pleased to see that somebody did a full working demonstration and included the server side callback code sample. This worked for me.

  • e

    Perfect!! Thank you!!

  • Guest

    Sorry, but I find this article difficult to understand.

  • kapil garg

    Do we need to know the name of the callback function which is on the server ?

  • sachin rathi

    I have made a call by AJAX with jsonp from jQuery to call Rest API through Android emulator. I got given error “Failed to load resource: net::ERR_NAME_NOT_RESOLVED”.

    var wcfServiceUrl = “http://dev3/DCLocalGateWay/LocalGateWay/RestGateWay.svc/GetMessage”;
    cache: false,
    url: wcfServiceUrl,
    //data: “{}”,
    type: “GET”,
    contentType: “application/javascript; charset=utf-8”,
    // jsonpCallback: “RestaurantMenu”,
    crossDomain: true,
    dataType: “json”,
    async: false,
    error: function (error) {
    alert(“Menu failed!”);
    success: function (response) {


    Please help

  • Great, so I just have to go to Google Places API and change their source code to rename their json. Thank you, this article is useless.

  • Awesome article! I’m adding that API directory to my bookmarks.

  • augur

    I just want to point out that the paragraph “A Possible Workaround” is a scaled down version of exactly what you describe in “Enter JSONP” using jQuery’s methodology. JSONP is JSONP is JSONP no matter what library is used they are all doing the same thing.

    • Satya Prakash

      can we call a jquery ajax call from java script code without dataType “jsonp”.
      I am facing this issue.
      can any one help me.

  • Danny Feliz

    Thank you man! :D

  • rongjie han

    Thank you man

  • Satya Prakash

    here is my code scripts :

    $(document).ready(function(e) {

    var roomAvailability = ‘{“accessKey” : “ea919f7d1d944afc40e129a1823dbffd”,”channelId” : “147”,”hotels” :[{hotelId” : 1,”rooms” : [{“roomid” : “2 “,”availability” : [{“date” : “2016-09-02″,”free” : 4},{“date” : “2016-09-03″,”free” : 4}]},{“roomid” : “1 “,”availability” : [{“date” : “2016-09-02″,”free” : 4},{ “date” : “2016-09-03″,”free” : 4 }]}]}]}’;


    url: “http://myserver:8080/api/daywiseInventory”,

    type: ‘POST’,

    data: roomAvailability,

    contentType: ‘application/json; charset-utf-8’,

    crossDomain: true,

    dataType: ‘json’,

    headers : {‘Access-Control-Allow-Origin’: ‘*’,’Access-Control-Allow-Methods’: ‘POST’},

    success: function (data) {





    error: function(xhr,status,error) {



    $(‘#msg’).html(“ERROR…! Please check the console (F12)”);





    • James Hibbard

      can we call a jquery ajax call from java script code without dataType “jsonp”.

      Yes, you can do that. I’m afraid I don’t understand your problem. Can you elaborate?

  • DrLightman

    Is anything missing under “Enter JSONP” example code? I don’t see any reference to the “jsonCallback” and I can’t figure out how could it work.

    • James Hibbard

      Nah, there’s nothing missing. The server’s response is wrapped in a jsonCallback function which you can see here. This gives you the opportunity to actually get at the data that the server returns, rather than just have it sit there. Does that make sense?

      • DrLightman

        Ah okay I got it, thank you.

  • James Hibbard

    Sorry, I don’t follow. What do you mean “hide the url”?

  • James Hibbard

    You have two quotes at the end of the url value.

    Using a tool like JSHint will catch this straight away.

  • Celeste Arlene Sinclair

    I tried your jsonp example exactly as written and got this:

    too much recursion[Learn More] everypage-4deb0db132744fb0c87cc719fe7b42ba955814162f416661abbb0f68fb6b7846.js:1:12942
    too much recursion[Learn More] everypage-4deb0db132744fb0c87cc719fe7b42ba955814162f416661abbb0f68fb6b7846.js:1:12967
    Object { meta: Object, data: Object } console_runner-5710c30fb566082d9fcb6e7d97ee7e3f2a326128c9f334a4231b6fd752b29965.js:1:2206

    What’s going on?

    • James Hibbard

      Oh dear, that doesn’t sound good.

      Debugging this in the comments section of the article will be a pain. Could you head on over to SitePoint and post your question in the JavaScript forum. If you tag me (@pullo) I’ll answer you there.

      • Celeste Arlene Sinclair

        Thanks, but it’s working now.

  • Kixeye User

    – am using spring boot and response body as JSON
    – am getting error is
    SyntaxError: missing ; before statement{“result”:”Failed”,”info”:”Record Not Found”}

    – My java Script, **Request failed: parsererror**, if i am using with out JSONP am geting crossDomain error
    var request = $.ajax({
    type: “GET”,
    url: _urls,
    data: data,
    dataType: “jsonp”,
    //headers:’Content-Type: application/json; charset=utf8′,
    headers : {‘Access-Control-Allow-Origin’: ‘*’,’Access-Control-Allow-Methods’: ‘GET’},
    //dataType: “jsonp”,
    contentType: ‘application/json; charset-utf-8’,
    //cache :true,
    /*error: function(jqXHR, textStatus, errorThrown) {
    alert(‘Error Message: ‘+textStatus);
    alert(‘HTTP Error: ‘+errorThrown);
    success: function (data) {

    request.done(function( msg ) {
    alert(” done”)
    });, textStatus,thrownError) {
    alert(“Request failed: ” +textStatus)
    alert(thrownError.toSource()+”…”+jqXHR.toSource()+” —– “+textStatus.toSource())

    • James Hibbard

      Hi, if you can make a self contained example that demonstrates your problem and post it to SitePoint forums (as mentioned to Celeste), I’ll see if I can help.

  • vsync

    in jQuery’s API they use `?jsoncallback=?`

    if I change it to just `callback=?` then I get an error… :/

    • James Hibbard

      The JSONP callback parameter varies depending on the server-side API. In the case of Flikr (the example you link to) it needs to be jsoncallback.

      From the Flickr API docs:

      To define your own callback function name, add the parameter jsoncallback with your desired name as the value.

  • Luciano Viana

    Hello, I would like to know if I can use the payment by card for the “transparent checkout”, such as “PayPal Plus”, without leaving the site that is a static html site, because I have already read that it is not possible because cross- And that requires having on a java or php server, does this proceed? Or that way you explained solves it?

Get the latest in JavaScript, once a week, for free.