Jump to content
Sign in to follow this  
jeffman

Perl does AJAX

Recommended Posts

Here we have a script that receives an AJAX POST, parses the request, and returns the appropriate data, in this case information about the directory that houses the calling document. Notice that it uses no libraries. CGI.pm doesn't handle AJAX very well (YMMV), and AJAX.pm is too complicated for a simple exercise like this (and most other applications as well). Here, the subroutine that parses the post data is generic enough that it can be used in any cgi context. It's also short and can even live in a "require" file.

#!/usr/bin/perlprint "Content-type: text/plain\n\n";sub main(){   readPostData() or print "foobar" and return;   for (my $i = 0; $NAMES[$i]; $i++){	  if ($NAMES[$i] eq "print"){printDirData($VALUES[$i]);}   }}# END main()sub readPostData(){ # a generic routine that can be copied and pasted with no changes   my $i;   my $buffer;   my @data;   read (STDIN, $buffer, $ENV {"CONTENT_LENGTH"}) or return 0;   @data = split (/&/, $buffer);   for ($i = 0; $data[$i]; $i++){	  ($NAMES[$i], $VALUES[$i]) = split (/=/, $data[$i]);	  $VALUES[$i] =~ tr/+/ /;	  $VALUES[$i] =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;   }   return 1;}# END readPostData()sub printDirData(){   my @list;   opendir MY_DIR, "." or print "Could not open directory" and exit;   @list = readdir (MY_DIR) or print "Could not read directory" and exit;   close (MY_DIR);   @list = grep(!/\.$/, @list);   for ($_[0]){#implicit matching used like switch	  /all/   and last;	  /files/ and @list = grep(-f, @list), last;	  /dirs/  and @list = grep(-d, @list), last;   }   @list = sort @list;   for (@list){print "$_\n";}}# END printDirectory()main();#end ajax.cgi

Here we have the matching HTML document with script. It's so generic it makes a useful model for any AJAX situation (though for simplicity's sake it only checks for returned errors, not broken pipe errors).

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>	<head>	   <title>Ajax test</title>	</head>	<body> 	   <button onclick= "hPostData('print=all')">List all</button>	   <button onclick= "hPostData('print=files')">List files</button>	   <button onclick= "hPostData('print=dirs')">List directories</button>	   <br>	   <textarea id='myText' rows='43' cols='30'></textarea> 	   <script type="text/javascript">		  var hObj;		  function hPostData(myData) {			 hObj = null;			 var myURL = "ajax.cgi";			 if (hObj = getHObject()){				hObj.onreadystatechange = hStateChanged;				hObj.open ('POST', myURL, true);				hObj.send (myData);			 }else {alert ("Cannot get an HTTP object");}		  }		  function hStateChanged() { 			if (hObj.readyState == 4) {			   if (hObj.status == 200) {				  printResponse(hObj.responseText);			   }else{				  alert ('Sorry: ' + hObj.status);			   }			}		  }		  function getHObject() {			 var hObj = null;			 try {hObj = new XMLHttpRequest();}			 catch (e) {				try {hObj = new ActiveXObject('Msxml2.XMLHTTP');}				catch (e) {hObj = new ActiveXObject('Microsoft.XMLHTTP');}			 }			 return hObj;		  }		  function printResponse(myText) {			 var myTA = document.getElementById('myText');			 myTA.value = myText;		  }	   </script> 	</body> </html>

Remember: perl scripts do not usually copy and paste very well. The usual villain is newline/carriage return characters. If you do want to paste this one, if you get an error, you might try deleting all the end-of-lines and then simply hitting your return key to reinsert the proper end-of line code. Or, you could just retype the thing.

Share this post


Link to post
Share on other sites

Shouldn't that title be "AJAX does Perl"? :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×