Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I have a form submiting data to a perl script and I am trying to read the data sent (JSON), but cant make it work, any help?
This is the jquery code sending serialized data to the perl script:
<script type="text/javascript" > $(function() { $(".submit").click(function() { var formData = $("#reply-form").serialize(); alert(formData); $.ajax({ type: "post", url: "code.pl?test=test", cache: false, data: formData, contentType: "application/json; charset=UTF-8", dataType: "json", success: function(data) //onSuccess, { alert(data); }, error: function(xhr, ajaxOptions, thrownError) { console.log('status: ' + xhr.status); console.log('thrownError:' + thrownError); } }); }); // return false to prevent normal browser submit and page navigation return false; }); </script>
Here is a simple Perl script to read the data sent I am trying:
#!/usr/bin/perl use strict; use warnings; use CGI; use CGI qw(:standard); use JSON; use Data::Dumper; my $q = new CGI; print $q->header("application/json"); my $data = decode_json($q->param('dataString')); print Dumper $data;

Thanks for looking!

Replies are listed 'Best First'.
Re: Read JSON data from a form
by Corion (Patriarch) on Dec 29, 2013 at 18:24 UTC

    You try to read a parameter named dataString but your Javascript never sends it.

    Maybe you can show us what parameters are actually received by the Perl code? Also, what error message are you receiving on the Perl side of things from the JSON module?

    Also, even if it works, currently your Perl script won't necessarily return a well-formatted JSON string to Javascript. Use encode_json instead of Data::Dumper for that.

      OK, the form sends stuff like this:
      my $name = $q->param( 'name' ) || ''; my $email = $q->param( 'email' ) || ''; my $zip = $q->param( 'zip' ) || '';
      But by serializing the data this code
      var formData = $("#reply-form").serialize(); alert(formData);
      adds all the values into a string. Doesnt this line: my $data = decode_json($q->param('dataString')); grabs all that the from is sending?

        No. What part of CGI mentions the magic name dataString, or what other documentation makes you assume that?

        If you send your elements via jQuery.serialize(), you will get the elements as separate parameters in the request and can retrieve them as you already showed in your first Perl snippet.

        Your second Perl snippet makes no sense in this context.

Re: Read JSON data from a form
by tangent (Parson) on Dec 29, 2013 at 20:06 UTC
    You seem to be confusing the send and return aspects. You are not sending JSON to the script as the serialize() method serializes a form's data into a query string, not JSON (this string can be decoded using the normal CGI methods). On the other hand, you are telling jQuery that your response will be JSON ( dataType: "json" in your javascript and $q->header("application/json") in your perl script) but you are not sending JSON back, just a plain string.

    I don't know your exact requirements but I suspect you don't need to send JSON to your script, you may however need to return JSON. This may help you to see the difference:

    Javascript

    <script type="text/javascript" > $(function() { $(".submit").click(function() { var formData = $("#reply-form").serialize(); alert(formData); $.ajax({ type: "post", url: "code.pl", cache: false, data: formData, dataType: "json", success: function(data) //onSuccess, { alert(data.calling_params); }, error: function() { alert( "Sorry, there was a problem!" ); } }); return false; }); }); </script>

    Perl

    use strict; use warnings; use CGI; use JSON; use Data::Dumper; my $q = new CGI; my $in = $q->Vars; my $string = Dumper ($in); my $response = encode_json( { calling_params => "$string" } ); print $q->header("application/json"); print $response;
      use CGI->param not CGI->Vars , CGI->Vars has caveats
        You are right, but I didn't know the names of the parameters at the time of writing. I can now see those from OP's reply so you could change the offending line to:
        my $in; $in->{'name'} = $q->param('name'); $in->{'email'} = $q->param('email'); # etc