<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>sue spence</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/sue_spence/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/sue_spence/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/sue_spence//71</id>
    <updated>2011-08-10T21:10:04Z</updated>
    <subtitle>Stuff I do with Perl and so forth</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>How to add JSONP support to a web service</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/sue_spence/2011/08/how-to-add-jsonp-support-to-a-web-service.html" />
    <id>tag:blogs.perl.org,2011:/users/sue_spence//71.2074</id>

    <published>2011-08-09T18:25:07Z</published>
    <updated>2011-08-10T21:10:04Z</updated>

    <summary>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...</summary>
    <author>
        <name>sue spence (virtualsue)</name>
        
    </author>
    
    <category term="jsonjsonprestperl" label="json jsonp REST Perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/sue_spence/">
        <![CDATA[<p>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:</p>

<pre><code>$.getJSON("http://www.thing.com/services/webservice_json?callback=?", 
         { "param" : "abc" },
         function(json) { 
             alert("Fetched " + json.field1 + ", " + json.field2); 
         });
</code></pre>

<p>So I needed to modify the web services to handle this.  Turns out this was really easy:</p>

<pre><code>use CGI; 
use JSON; 
my $c = CGI-&gt;new; 

# Get the callback function name 
my $callback = $c-&gt;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=&gt;'1'}); 

if ($callback) { 
    print $callback . '(' . $json . ');'; 
} else { 
    print $json,"\n"; 
}</code></pre>]]>
        
    </content>
</entry>

</feed>
