How to add JSONP support to a web service
I needed to do this yesterday, so that a developer could work on a project on his own machine while accessing some REST services I developed on an intranet server. Cross-domain requests are prohibited by the same origin policy security that govern client-side Javascript programs. JSONP gets around this by sending back a Javascript function which encloses the JSON data, rather than just the JSON data. This is known as a callback and is used like this:
$.getJSON("http://www.thing.com/services/webservice_json?callback=?",
{ "param" : "abc" },
function(json) {
alert("Fetched " + json.field1 + ", " + json.field2);
});
So I needed to modify the web services to handle this. Turns out this was really easy:
use CGI;
use JSON;
my $c = CGI->new;
# Get the callback function name
my $callback = $c->param('callback');i
if ($callback) {
print 'Access-Control-Allow-Origin: *';
print 'Access-Control-Allow-Methods: GET';
print "Content-type: application/javascript\n\n";
} else {
# Header for access via browser, curl, etc.
print "Content-type: application/json\n\n";
}
# Fake up some sample data
my %json;
$json{'IP'} = $ENV{REMOTE_ADDR};
$json{'useragent'} = $ENV{HTTP_USER_AGENT};
$json{'list'} = [ 'a', 'b', 'c', 'd', 'e' ];
# Convert %json to a scalar containing a JSON formatted string
my $json = to_json(\%json, {pretty=>'1'});
if ($callback) {
print $callback . '(' . $json . ');';
} else {
print $json,"\n";
}
Leave a comment