How to make a JSONP request from Javascript without JQuery? How to make a JSONP request from Javascript without JQuery? javascript javascript

How to make a JSONP request from Javascript without JQuery?


function foo(data){    // do stuff with JSON}var script = document.createElement('script');script.src = '//example.com/path/to/jsonp?callback=foo'document.getElementsByTagName('head')[0].appendChild(script);// or document.head.appendChild(script) in modern browsers


Lightweight example (with support for onSuccess and onTimeout). You need to pass callback name within URL if you need it.

var $jsonp = (function(){  var that = {};  that.send = function(src, options) {    var callback_name = options.callbackName || 'callback',      on_success = options.onSuccess || function(){},      on_timeout = options.onTimeout || function(){},      timeout = options.timeout || 10; // sec    var timeout_trigger = window.setTimeout(function(){      window[callback_name] = function(){};      on_timeout();    }, timeout * 1000);    window[callback_name] = function(data){      window.clearTimeout(timeout_trigger);      on_success(data);    }    var script = document.createElement('script');    script.type = 'text/javascript';    script.async = true;    script.src = src;    document.getElementsByTagName('head')[0].appendChild(script);  }  return that;})();

Sample usage:

$jsonp.send('some_url?callback=handleStuff', {    callbackName: 'handleStuff',    onSuccess: function(json){        console.log('success!', json);    },    onTimeout: function(){        console.log('timeout!');    },    timeout: 5});

At GitHub: https://github.com/sobstel/jsonp.js/blob/master/jsonp.js


What is JSONP?

The important thing to remember with jsonp is that it isn't actually a protocol or data type. Its just a way of loading a script on the fly and processing the script that is introduced to the page. In the spirit of JSONP, this means introducing a new javascript object from the server into the client application/ script.

When is JSONP needed?

It is 1 method of allowing one domain to access/ process data from another in the same page asyncronously. Primarily, it is used to override CORS (Cross Origin Resource Sharing) restrictions which would occur with an XHR (ajax) request. Script loads are not subject to CORS restrictions.

How is it done

Introducing a new javascript object from the server can be implemented in many ways, but the most common practice is for the server to implement the execution of a 'callback' function, with the required object passed into it. The callback function is just a function you have already set up on the client which the script you load calls at the point the script loads to process the data passed in to it.

Example:

I have an application which logs all items in someone's home. My application is set up and I now want to retrieve all the items in the main bedroom.

My application is on app.home.com. The apis I need to load data from are on api.home.com.

Unless the server is explicitly set up to allow it, I cannot use ajax to load this data, as even pages on separate subdomains are subject to XHR CORS restrictions.

Ideally, set things up to allow x-domain XHR

Ideally, since the api and app are on the same domain, I might have access to set up the headers on api.home.com. If I do, I can add an Access-Control-Allow-Origin: header item granting access to app.home.com. Assuming the header is set up as follows: Access-Control-Allow-Origin: "http://app.home.com", this is far more secure than setting up JSONP. This is because app.home.com can get everything it wants from api.home.com without api.home.com giving CORS access to the whole internet.

The above XHR solution isn't possible. Set up JSONP On my client script: I set up a function to process the reponse from the server when I make the JSONP call.:

function processJSONPResponse(data) {    var dataFromServer = data;}

The server will need to be set up to return a mini script looking something like "processJSONPResponse('{"room":"main bedroom","items":["bed","chest of drawers"]}');" It might be designed to return such a string if something like //api.home.com?getdata=room&room=main_bedroom is called.

Then the client sets up a script tag as such:

var script = document.createElement('script');script.src = '//api.home.com?getdata=room&room=main_bedroom';document.querySelector('head').appendChild(script);

This loads the script and immediately calls window.processJSONPResponse() as written/ echo/ printed out by the server. The data passed in as the parameter to the function is now stored in the dataFromServer local variable and you can do with it whatever you need.

Clean up

Once the client has the data, ie. immediately after the script is added to the DOM, the script element can be removed from the DOM:

script.parentNode.removeChild(script);