1

I need to be able to decode multiple parameters from the data portion of an ajax call to a perl cgi script. I know that everything else is working with my code, but for whatever reason I can't seem to get the decode method of the JSON module to work properly to restore the data from JSON format to parameters again. The data in my jQuery ajax call is set up like this, which is correct.

data: {
    maxRows: 5,
    productName: request.term
}

However, something is wrong with the way that I'm trying to parse it into perl.

my $json = JSON->new->utf8->allow_nonref;
my $json_text = $cgi->param('data');
my $json_array = $json->decode( $json_text );

I know that the correct end result should be an array of hashes. If I can get that far I know I'll be fine. However, my decode line does not work and actually causes the whole script to fail when it's executed.

I have looked around extensively and I just can't figure this out. I'm pretty sure it's some very small tweak.

Am I getting the parameter correctly by using $cgi->param('data') ? Does it end up being named data, or is it something else?

sage88
  • 4,104
  • 4
  • 31
  • 41

2 Answers2

2

If you send this as an (asyncronous) POST request from jQuery to your Perl script, you need to give it a parameter for CGI to parse. Otherwise you will need to look at the whole body. CGI cannot parse this data thing, becaue it is not in the correct form.

The request's body would have to be in this form for $cgi->param('data') to work:

data=data:{maxRows:5,productName:request.term}

Instead, try using POSTDATA to get the complete body of the HTTP request that was sent to your script.

my $data = $query->param('POSTDATA');
my $json_array = $json->decode( $data );

See the CGI doc for more info. This question might also be helpful: How can I get the entire request body with CGI.pm?

Community
  • 1
  • 1
simbabque
  • 53,749
  • 8
  • 73
  • 136
  • Could the downvoter please explain what the problem with this answer is? – simbabque Apr 09 '13 at 13:36
  • Wasn't me. I gave you a +1. I think this is along the lines of how this problem should be solved but as currently stated doesn't work. I played around with it for a couple hours and couldn't get it to work properly either. Ended up just using the quasi-hack approach shown here: http://www.ibm.com/developerworks/webservices/library/ws-simplelogin/?ca=drs- – sage88 Apr 10 '13 at 04:03
  • @sage88 I think it makes sense now what you wanted to do. You really just needed to submit a few parameters with your POST. There's no need for JSON in that. – simbabque Apr 10 '13 at 07:46
1

Your JSON data isn't valid. Use JSONLint to validate your data. A correct example of JSON data would be as follows:

{
    "maxRows": 5,
    "productName": "request.term"
}

If you omit the data: key and surround all keys inside the object with quotation marks, you should be fine. The expression request.term isn't allowed outside of a string since it isn't defined.

Edit

Okay, you're using jQuery to send JSON data. Have a look here to see how to correctly send JSON from jQuery via Ajax. Besides, I'd recommend to use FireBug to check what data is posted by jQuery.ajax.

Community
  • 1
  • 1
Marcellus
  • 1,277
  • 8
  • 7
  • Are you sure? The jQuery API and demos has it done they way I have it above. I even tested the code for this demo: http://jqueryui.com/autocomplete/#remote-jsonp myself and it worked. I just don't have the server side script to look at to see how it was parsed there. – sage88 Apr 09 '13 at 11:10
  • Yeah I've seen that method before, and I guess I was just trying to reach a more robust understanding of how to get AJAX data using CGI.pm. This approach just seems like a hack by comparison. http://www.ibm.com/developerworks/webservices/library/ws-simplelogin/ this uses the same concept. I know the way that I have it currently works, I just don't know the parsing technique that geonames.org is using. But I suppose beggars can't be choosers. – sage88 Apr 09 '13 at 11:24
  • On another note I'm using Google Canary with Developer Tools turned on. I can see the query string parameters coming out as: maxRows:5 productName:bi (if I type in bi at the input). So even the developer tool is parsing them correctly, which is particularly irksome. – sage88 Apr 09 '13 at 11:26
  • I believe that the Perl JSON module is quite picky about JSON syntax. – Marcellus Apr 09 '13 at 11:31
  • I get that, but I think my problem is with the CGI.pm module, not the JSON.pm module. Hmm going to test where it gets defined... – sage88 Apr 09 '13 at 11:43
  • I ended up using a fairly similar approach to this. I don't like it as it's not how the API shows it being done, but it does work. Giving you a plus one but not the correct answer. – sage88 Apr 10 '13 at 04:01