为什么我的Perl CGI脚本会出现空白页面?

时间:2010-05-01 20:34:27

标签: perl

用户使用表单输入产品代码,价格和名称。然后,该脚本将其添加到数据库或从数据库中删除它。如果用户试图删除不在数据库中的产品,则会收到错误消息。成功添加或删除后,他们也会收到消息。但是,当我测试它时,我只得到一个空白页面。 Perl没有提出任何警告,语法错误或任何东西;说一切都很好,但我仍然只是得到一个空白页。

剧本:

    #!/usr/bin/perl
#c09ex5.cgi - saves data to and removes data from a database
print "Content-type: text/html\n\n";
use CGI qw(:standard);
use SDBM_File;
use Fcntl;
use strict;

#declare variables
my ($code, $name, $price, $button, $codes, $names, $prices);


#assign values to variables
$code = param('Code');
$name = param('Name');
$price = param('Price');
$button = param('Button');

($code, $name, $price) = format_input();
($codes, $names, $prices) = ($code, $name, $price);

if ($button eq "Save") {
      add();
}
elsif ($button eq "Delete") {
      remove();
}
exit;


sub format_input {
         $codes =~ s/^ +//;
         $codes =~ s/ +$//;
         $codes =~ tr/a-z/A-Z/;
         $codes =~ tr/ //d;
         $names =~ s/^ +//;
         $names =~ s/ +$//;
         $names =~ tr/ //d;
         $names = uc($names);
         $prices =~ s/^ +//;
         $prices =~ s/ +$//;    
         $prices =~ tr/ //d;
         $prices =~ tr/$//d;
    }


sub add {
   #declare variable
   my %candles;

 #open database, format and add record, close database
     tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
          or die "Error opening candlelist. $!, stopped";

     format_vars();
     $candles{$codes} = "$names,$prices";
     untie(%candles);

 #create web page      
      print "<HTML>\n";
      print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
      print "<BODY>\n";
      print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n";
      print "Candle: $codes $names $prices</FONT>\n";
      print "</BODY></HTML>\n";
      } #end add


sub remove {
   #declare variables
   my (%candles, $msg);

 tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
          or die "Error opening candlelist. $!, stopped";

     format_vars();

     #determine if the product is listed
     if (exists($candles{$codes})) {
          delete($candles{$codes});
          $msg = "The candle $codes $names $prices has been removed.";
        }
     else {
     $msg = "The product you entered is not in the database";
     }
     #close database
     untie(%candles);

#create web page
print "<HTML>\n";
print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
print "<BODY>\n";
print "<H1>Candles Unlimited</H1>\n";
print "$msg\n";
print "</BODY></HTML>\n";
}

3 个答案:

答案 0 :(得分:1)

在命令行运行它:

perl something.cgi Button=Save

...给我一个错误:

Undefined subroutine &main::format_vars called at something.pl line 55.

如果我将format_vars()的两个引用更改为“format_input()”,我会得到我认为正确的输出。

答案 1 :(得分:1)

除非调用addremove,否则您不会打印Content-Type标头以外的任何输出。问题是如果没有点击任何按钮,你忘了显示一个表格(可能是一个包含按钮的表格)。

修改:复制已发布的代码并进行一些清理,然后在网址http://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Savehttp://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Delete调用它,我会获得正确的HTML输出。用于此目的的清理版本代码为:

#!/usr/bin/perl

use strict;
use warnings;

print "Content-type: text/html\n\n";
use CGI qw(:standard);
use SDBM_File;
use Fcntl;
use strict;

#declare variables
my ($code, $name, $price, $button, $codes, $names, $prices);


#assign values to variables
$code = param('Code');
$name = param('Name');
$price = param('Price');
$button = param('Button');

($code, $name, $price) = format_input();
($codes, $names, $prices) = ($code, $name, $price);

if ($button eq "Save") {
  add();
}
elsif ($button eq "Delete") {
  remove();
}
exit;


sub format_input {
  $codes =~ s/^ +//;
  $codes =~ s/ +$//;
  $codes =~ tr/a-z/A-Z/;
  $codes =~ tr/ //d;
  $names =~ s/^ +//;
  $names =~ s/ +$//;
  $names =~ tr/ //d;
  $names = uc($names);
  $prices =~ s/^ +//;
  $prices =~ s/ +$//;
  $prices =~ tr/ //d;
  $prices =~ tr/$//d;
  }

sub add {
#   #declare variable
#   my %candles;
#
# #open database, format and add record, close database
#     tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
#          or die "Error opening candlelist. $!, stopped";
#
#     format_vars();
#     $candles{$codes} = "$names,$prices";
#     untie(%candles);

 #create web page      
 print "<HTML>\n";
 print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
 print "<BODY>\n";
 print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n";
 print "Candle: $codes $names $prices</FONT>\n";
 print "</BODY></HTML>\n";
 } #end add


sub remove {
#   #declare variables
#   my (%candles, $msg);
#
# tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
#          or die "Error opening candlelist. $!, stopped";
#
#     format_vars();
#
#     #determine if the product is listed
#     if (exists($candles{$codes})) {
#          delete($candles{$codes});
#          $msg = "The candle $codes $names $prices has been removed.";
#        }
#     else {
#     $msg = "The product you entered is not in the database";
#     }
#     #close database
#     untie(%candles);

  #create web page
  print "<HTML>\n";
  print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
  print "<BODY>\n";
  print "<H1>Candles Unlimited</H1>\n";
#  print "$msg\n";
  print "<p>Called remove</p>";
  print "</BODY></HTML>\n";
  }

请注意,启用warnings会产生大量“未初始化的值”警告,因为您获得$code vs $codes$name vs {{1和} $names vs $price以错误的方式相互混淆。 (提示:您指定了$prices,但($code, $name, $price) = format_input();未返回三个值。)

我怀疑,正如先前评论中所建议的那样,您再次/仍然存在案例敏感问题。我第一次尝试测试失败是因为我在URL中使用了“button = Save”而不是“Button = Save”。按照惯例,HTTP请求参数名称通常都是小写的,并且有充分的理由,因为它有助于避免那种问题。

其他随机评论:

  • 您可以在首次分配变量时声明变量,例如format_input。这通常被认为是更好/首选的做法,因为尽可能晚地宣布您的声明有助于最小化变量的范围。

  • my $code = param('Code');中,format_inputs/^ +//; s/ +$//;都是多余的,因为tr/ //d;也会删除前导和尾随空格。

  • 获取参数值时,如果参数为空/缺失,则应提供默认值,或检查是否为空/缺失,并向用户显示错误。

  • 如果tr缺失或无效,您应该在else后面有一个最终的elsif ($button eq "Delete")子句,以显示错误。是的,我知道这个脚本是从一个特定的表单调用的,所以它应该“总是”有一个有效的$button,但绕过表单并提交任何一组值(有效或无效)是微不足道的直接编写脚本,因此您仍然需要验证并验证服务器端的所有内容,因为您不知道它实际来自何处或客户端是否正确验证了它。

答案 2 :(得分:0)

这就是我运行脚本的方式,它确实产生了正确的结果。确保您托管网站的任何地方,都安装了正确的PERL模块。

注意:我正在使用的托管服务(BlueHost)要求我通过#!/ usr / bin / perlml

调用我的Perl模块
   #!/usr/bin/perlml

   use strict;
   use warnings;

   print "Content-type: text/html\n\n";
   use CGI qw(:standard);
   use SDBM_File;
   use Fcntl;
   use strict;

   #declare variables
   my ($code, $name, $price, $button, $codes, $names, $prices);


   #assign values to variables
   $code = param('Code');
   $name = param('Name');
   $price = param('Price');
   $button = param('Button');

   ($codes, $names, $prices) = format_input();
   ($codes, $names, $prices) = ($code, $name, $price);

   if ($button eq "Save") {
   add();
   }
   elsif ($button eq "Delete") {
   remove();
   }
   exit;


   sub format_input {
   $codes =~ s/^ +//;
   $codes =~ s/ +$//;
   $codes =~ tr/a-z/A-Z/;
   $codes =~ tr/ //d;
   $names =~ s/^ +//;
   $names =~ s/ +$//;
   $names =~ tr/ //d;
   $names = uc($names);
   $prices =~ s/^ +//;
   $prices =~ s/ +$//;
   $prices =~ tr/ //d;
   $prices =~ tr/$//d;
   }

   sub add {
   #declare variable
   my %candles;

   #open database, format and add record, close database
   tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
   or die "Error opening candlelist. $!, stopped";

   format_input();
   $candles{$code} = "$name,$price";
   untie(%candles);

   #create web page      
   print "<HTML>\n";
   print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
   print "<BODY>\n";
   print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n";
   print "Candle: $codes, $names, $prices</FONT>\n";
   print "</BODY></HTML>\n";
   } #end add

   sub remove {
   #declare variables
   my (%candles, $msg);

   tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
   or die "Error opening candlelist. $!, stopped";
   format_input();

   #determine if the product is listed
   if (exists($candles{$code})) {
   delete($candles{$code});
   $msg = "The candle $code, $name, $price has been removed.";
   }
   else {
   $msg = "The product you entered is not in the database";
   }
   #close database
   untie(%candles);

   #create web page
   print "<HTML>\n";
   print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
   print "<BODY>\n";
   print "<H1>Candles Unlimited</H1>\n";
   print "$msg\n";
   print "</BODY></HTML>\n";
   }