How do I receive and respond to Ajax requests in Perl? - ajax

I have a client-side appliction which submits some data via AJAX POST request (request.open("POST", url, flag)) to my Perl CGI script.
How do I retrieve this data with Perl and return some other data (AJAX response)?

The same way you would handle any POST request. You need a CGI script at url that receives the POST and returns whatever the JavaScript is expecting. The only difference from a normal HTML form POST is the Content-Type that you would be receiving and transmitting.

Use the core CGI module. E.g.
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $foo = $q->param( 'foo' );
print $q->header;
print "You said $foo";
If your app will be large and complex, you may want to investigate one of the Perl web application frameworks, like CGI::Application or Catalyst.

The basic model for CGI scripts is "read from STDIN, write to STDOUT". At the input stage, the environment variable CONTENT_LENGTH gives the length in bytes of what is to be read from STDIN. At the output stage, you also need to send basic HTTP headers, which minimally is one line "Content-Type" with a mime type, like text/html, or text/plain, etc. plus a blank line:
Content-Type: text/plain
<your data starts here>
In the case of XMLHttpRequest, you completely control the format of the data, so how you parse the input from STDIN is up to you. Similarly you can lie in the mime type, and send whatever you want as a response.
JSON is a nice format for sending data from Perl to JavaScript.

use CGI;
my $q = CGI->new;
my $xml = $q->param('POSTDATA');

Related

How to send a post from twillio webhook using the body instead the params in the request?

There is a way to config the Twilio webhooks in the conversation product to send a post request to an endpoint and in the body send the information instead in the params?
You would pass a payload of the JSON you want to send in your post body and then pass in a header called x-www-form-urlencoded which tells Twilio that you want the parameters to be sent in the body as form data. I'm not sure if it's limited to only a few parameters or not but I know that it works with \"To\" and \"From\" (as they need to be URL encoded). It would definitely work with MessageSid.
You could also use the \"Bulk\" post body format, which is just JSON. This would allow you to pass more parameters since it's just JSON. (You don't need to url encode them if you do this, so no need to have x-www-form-urlencoded header.)
{
\"To\": \"+15551235555\",
\"From\": \"+15551234567\",
\"Body\": \"A text message\",
...: ...
}
You should be able to send the information you want, along with the headers, from your endpoint and have it pass through Twilio.
Looks like this:
curl -X POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages -d 'From=%2B15551234567&To=%2B15551235555&Body=Test' -u '{AccountSid}:{AuthToken}'
You can pass any JSON you want as a body using this option but make sure you've set your \"Content-Type\" header to \"application/x-www-form-urlencoded\". This is pretty straightforward and makes it easy to pass in whatever parameters you want.
This isn't limited to text messages! This is exactly how I push data back into a Conversation or Action resource too so it'll work for things like card pushes too! You can use this to programmatically create a response that Twilio will process and then act on in your Conversation or Action instance.
And yeah … if you're going to support a webhook that takes form data then I would suggest adding some basic security checks since anyone could just post random stuff as form data if they wanted and get access to your endpoint. I'd recommend checking the Request Method as well to make sure it's POST.
If you're worried about someone passing in a bad value then you can just check the request body against some regex. I'd recommend checking the Twilio-To and Twilio-From params as well. You could also use the request header too, which is passed along with all webhooks:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: xxx');

What is the "accept" part for?

When connecting to a website using Net::HTTP you can parse the URL and output each of the URL headers by using #.each_header. I understand what the encoding and the user agent and such means, but not what the "accept"=>["*/*"] part is. Is this the accepted payload? Or is it something else?
require 'net/http'
uri = URI('http://www.bible-history.com/subcat.php?id=2')
http://www.bible-history.com/subcat.php?id=2>
http_request = Net::HTTP::Get.new(uri)
http_request.each_header { |header| puts header }
# => {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], "accept"=>["*/*"], "user-agent"=>["Ruby"], "host"=>["www.bible-history.com"]}
From https://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#z3
This field contains a semicolon-separated list of representation schemes ( Content-Type metainformation values) which will be accepted in the response to this request.
Basically, it specifies what kinds of content you can read back. If you write an api client, you may only be interested in application/json, for example (and you couldn't care less about text/html).
In this case, your header would look like this:
Accept: application/json
And the app will know not to send any html your way.
Using the Accept header, the client can specify MIME types they are willing to accept for the requested URL. If the requested resource is e.g. available in multiple representations (e.g an image as PNG, JPG or SVG), the user agent can specify that they want the PNG version only. It is up to the server to honor this request.
In your example, the request header specifies that you are willing to accept any content type.
The header is defined in RFC 2616.

Do I need to send the data in $.ajax as json?

I have an $.ajax request that's sending the data in a serialize() and gets a json array in return. It works perfectly without any issues on Chrome develop's tools and Firefox's firebug. My question is, do I HAVE to send the data(user inputs) as json? I need json for the response but not for the request.
No, you send the data however you like but keep in mind how you send it will affect how you can retrieve it.
Also you aren't sending JSON in your request as .serialize() does not return JSON it returns a text string in standard URL-encoded notation.
No, you don't need to send it as JSON. You can send it in any other format, but your receiver will need to know how to interpret it. Usually people use JSON or XML since your receiver can easily parse these types of data.
You'll need to set the content-type, then you can tell the receiver how to process this content-type.

How do use JSON body in REST requests?

I am developing an API using Codeigniter and Phils RESTserver. I know how to send the request body in normal Form format but how can I send it as a JSON object instead?
I do this now:
lastname=bond
I want to do this instead:
{"lastname" : "bond"}
I tried to just replace the Content type header from:
application/x-www-form-urlencoded
In to this:
application/json
This did not do anything. Codeigniter says the POST array is empty.
If I understood correctly you want to create a request that contains a JSON node inside the request body. Assuming this, I think it's not possible to create such a request using simple HTML form tags as your browser always will try to pack your input vars in a querystring like format.
You will need JavaScript to achive this (I think all popular libs like Scriptacoulous or JQuery comes with helper methods for this).

ExtJs3. Defect when the upload file

To upload a file using inputType: 'file', and for a form prescribed fileUpload: true.
Everything works fine, the file is saved. But after saving the file block success (from ajax request) is not satisfied. Ie all the stops to waitMsg: 'Saving Data ...'.
What could be wrong?
Also, remember to set the Content-Type header to correct MIME type in your server response: "text/html". Anything else will result in ExtJS throwing an error when decoding your response.
In PHP, this can be done with
<?php
header('Content-type: text/html');
echo json_encode(array('success' => true));
?>
From ExtJS API docs:
If the server is using JSON to send the return object, then the Content-Type header must be > set to "text/html" in order to tell the browser to insert the text unchanged into the document body.
Characters which are significant to an HTML parser must be sent as HTML entities, so encode > "<" as "<", "&" as "&" etc.
Make sure you do escape special HTML characters as suggested. If you don't, ExtJS may still succeed in parsing the server response but with unexpected twists: single quotes in HTML-like strings turn into "', etc.
Maybe you should send back server result to extjs form by print this on server:
echo '{success:true, data: "save" }'

Resources