Over a million developers have joined DZone.

JSONP request in Adobe Air

DZone's Guide to

JSONP request in Adobe Air

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

With the jQuery API browser my key aim was to build an app that worked both in the Adobe Air environment and without any changes work on the web.

Typically, the environment is the same, with a few exceptions - one of which I ran in to yesterday.

Making a JSONP call simply doesn't return back to the application.

So here's a work around to get JSONP to work in Adobe Air.

The Problem

Originally I was trying to do a simple JSONP, by creating a script element, setting the source and inserting it in to the body. Although using the DOM inspector for Air showed that the element was in place, and the resource had been loaded, the callback never triggered. Nor was there an error.

I'm not completely sure of the actual source of the problem, but my suspicion is that Air may be ignoring the src attribute being set (since they say it's prohibited anyway - search for 'script.src').

I did try messing around with iframes and bridges, and googling, but there didn't seem to be any resources that explained how to get this to work.

Very simply, here's an example I would expect to work:

function jsonFlickrApi(data) {
alert('jsonp completed: ' + data.photos.photo.length);

// I've stripped the api key for the purpose of this article
var url = 'http://www.flickr.com/services/rest/?method=' +

var script = document.createElement('script');
script.src = url;

This works fine on the web, and pops up an alert saying it found 10 photos.

The same code in Adobe Air does nothing.

Note that I know this particular API could be called as XML and loaded via a direct Ajax call. My particular problem only supported JSONP requests.

The Solution

The solution is to use Ajax, combined with JSON combined with a prefilter function.

I'm including jQuery to simplify the Ajax request.

I make the JSON call, and I will use substr to strip out (and cache) the function name using the dataFilter function. Once the real JSON is passed in to the success function, I will look up the original function on the global window object and call the function manually. The follow code also support calling methods on objects (though I've only tested it on one method deep in a global object, i.e. myObject.success(data)).

// the same function exists to capture the JSONP success
function jsonFlickrApi(data) {
alert('jsonp completed: ' + data.photos.photo.length);

var url = 'http://www.flickr.com/services/rest/?method=' +

// the variable to cache the original function name
var fnStr = '';
url: url,
dataType: 'json', // note we're using json rather than jsonp
dataFilter: function (data) {
// data is the original string such as: jsonFlickrApi({...})

fnStr = data.substr(0, data.indexOf('('));
var start = data.indexOf('(');

// return everything in between the 'jsonFlickrApi(' and last ')'
return data.substr(start + 1, data.lastIndexOf(')') - start - 1);
success: function (data) {
// work out the original name space the jsonp function was on
var ns = fnStr.split('.'), p = window, last = window, i;
for (i = 0; i < ns.length; i++) {
last = p;
p = p[ns[i]] || p;

// call the function against the content of the parent
// i.e. this may just be window.jsonFlickrApi, but it
// could also be window.flickr.update(data)
p.call(last, data);

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.


Published at DZone with permission of Remy Sharp, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}