Cross-Domain with Sinatra / Rack and JSONP

There are several situations one might want to do cross-domain (/cross-site) AJAX-requests. Probably you experience the security borders of modern browsers very fast.
JSONP is a hack for JSON that provides a great workaround. It means sending a callback with the URL (eg. ?callback=sampleFunction). Server-sided we setup our application to respond with a JSON body wrapped in a function named like our callback function. In this case

sampleFunction({
  "ourData": [{
    "title": "is an array"
  },
    "title": "..."
  }]   
})

What we have to do (Sample)

Frontend
JS-Frameworks like jQuery are smart enough to send such requests with ease. Lets write a simple function with jQuery:

$.ajax({
  type: 'get',
  url: 'file.json',
  dataType: 'jsonp',
  success: function(data) {
    doSomethingWith(data);
  }
})

Let’s see how to setup the server:
Using Ruby and Rack it becomes very simple to beautifully provide regular JSON for non-JSONP clients and JSONP for jQuery & Co.
Simply use the rack middleware rack-contrib by Ryan Tomayko

gem install rack-rack-contrib --source=http://gems.github.com/

If you’re using pure rack, put this in your config.ru

require 'rack/contrib/jsonp'
use Rack::JSONP

Using Sinatra, I’d put it somewhere with my config files.
Let’s see how a sample Sinatra application could look like:

require 'sinatra'
require 'json'
require 'rack/contrib/jsonp'
 
use Rack::JSONP
 
before do
  content_type :json
end
 
get '/posts' do
  Posts.find.to_a.to_json
end

That simple, this powerful.

  1. Helios says:

    I Like! Comprehensive and awesome workaround. :-)

Leave a Reply
  1. (required)
  2. (will not be published) (required)