How can I send a JSON response from a Perl CGI program?

47,781

Solution 1

I am doing this in a perl/cgi program.

I use these in the top of my code:

use CGI qw(:standard);
use JSON;

Then I print the json header:

print header('application/json');

which is a content type of:

Content-Type: application/json

And then I print out the JSON like this:

my $json->{"entries"} = \@entries;
my $json_text = to_json($json);
print $json_text;

My javascript call/handles it like this:

   $.ajax({
        type: 'GET',
        url: 'myscript.pl',
        dataType: 'json',
        data: { action: "request", last_ts: lastTimestamp },
        success: function(data){
            lastTs = data.last_mod;
            for (var entryNumber in data.entries) {
                 //Do stuff here
            }
        },
        error: function(){
            alert("Handle Errors here");
        },
        complete: function() {
        }
    });

You don't necessarily have to use the JSON library if you don't want to install it, you could print straight JSON formatted text, but it makes converting perl objects to JSON prety easy.

Solution 2

Here is how to generate the request in Mason, the web framework for Perl.

Mason is analogous to Pylons or Ruby On Rails.

<%init>

use JSON;

my %hash = { a => 'a', b => 'b' };
my @list = ( 1, 2, \%hash );

# Mason object $r for Apache requests, automatically sets the header
$r->content_type('application/json');

# Pass a reference to anything (list, hash, scalar) for JSON to encode
my $json = new JSON;
print $json->encode(\@list);

</%init>

And then handle it in Prototype, the JavaScript web abstration:

var req = new Ajax.Request('request.html', {
    method: 'get',
    parameters: {
        whatever: 'whatever'
    },
    onCreate: function() {
        // Whatever
    },
    onSuccess: function(response) {
        // This only works if you set the 'application/json' header properly
        var json = response.responseJSON;

        // Since you sent a list as the top-level thing in the JSON,
        // then iterate through each item
        json.each(function(item) {
            if (item instanceof Object) {
                item = new Hash(item);
            } else if (item instanceof Array) {
                // Do array stuff
            } else {
                // Do scalar stuff
            }
        });
    },
    onFailure: function() {
        // Failed
    }
});

Solution 3

Even if you specify the type "application/json" you still need to parse the text. jQuery do this for you, using the $.getJSON function,ie:

$.getJSON("http://someurl.com/blabla.json",{some: "info"},function(json){
  alert(json["aKey"]["anotherOne"]);
});

(here the specs).

But maybe you are already aware of this, so the problem resides somewhere else: can you please tell us a sample of your json response, because maybe the problem is that is not valid. It's not really clear to me why you say that "doesnt seems to be recognised": when I write json services the first test I do is to call them on the browser and maybe fire up firebug and try to parse it (so yes the response it's a text response, but javascript it's still quite happy to parse it and return a json object).

Share:
47,781
oz19
Author by

oz19

Updated on November 29, 2020

Comments

  • oz19
    oz19 over 3 years

    I am writing a JSON response from a perl/cgi program. The header's content type needs to be "application/json". But it doesn't seems to be recognized as response is thrown as a text file.

    I would be capturing response using JSON library of jQuery. Where am I missing in sending the JSON response.

    • Paul Tomblin
      Paul Tomblin over 15 years
      How are you sending the response? Are you using CGI.pm?
    • oz19
      oz19 over 15 years
      Yes. I got it working using the third answer. Thanksk anyways
    • Mr. Muskrat
      Mr. Muskrat over 15 years
      You should accept the third answer then (click the check mark).
    • brian d foy
      brian d foy over 15 years
      Sample code showing what you have already tried is often helpful. :)
    • Horatio Alderaan
      Horatio Alderaan over 15 years
      Is there a third answer?
  • oz19
    oz19 over 15 years
    I was having errors in my JSON . Thanks a lot, it worked like a charm
  • Neil
    Neil over 14 years
    You should use 'application/json' as the header, and find some way to set the header in the request with your web framework, since printing the header won't necessarily work.