0

我是 Perl 新手。我正在尝试根据前人的工作和书籍进行学习,例如Learning PerlModern Perl。我正在尝试更新此脚本,该脚本解释 HTML 表单中的数据并将其写入文本文件,因为我们的实验室有兴趣重新启动并运行它。最初的脚本是为在 Linux 服务器上使用而编写的,但我们已经从 Linux 切换到 Windows 服务器。

我没有管理员权限查看错误消息的服务器是带有 ActivePerl 的 Windows 服务器。我很难找出 Windows 等效路径来告诉 Perl 脚本在哪里写入信息。从与管理员的交谈中,我们的 Intranet 似乎映射到了E:驱动器上,尽管这可能不是致命错误。

当我在表单上输入数据后尝试在浏览器中运行此脚本时,它只返回一个泛型:

CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers.

任何提示、文档、教程都将受到赞赏。谢谢你。

#!C:\perl\bin\perl.exe -w -t

# Good programming practice dictates...
use strict;
use warnings;

# CGI.pm -- makes life easy
#Carp qw(fatalsToBrowser); outputs the error messages to the browser since there is no terminal to output error messages to. Should be removed before script is used in production.
use CGI::Carp qw(fatalsToBrowser) or die "Problems loading CGI.pm";

# Initialize the CGI Interface
my($cgi) = new CGI;

# Print the Header
print $cgi->header();

#The dbmopen call is now de-appreciated. IE: it no longer works
#Kept for archival reasons
#if (! dbmopen(%DB, "/vol/research/docs/old_site_files/eyesignup/data/eyesignup_NEW.dat", 0666))
#   {
#   print "Error -- Cannot open database.\n";
#   exit;
#   }
# Tie is the correct way to do it now. But first we are going to experiment with writing to a flat .txt file.
open (Datastore, '>>',"E:/intranet/sds/research/docs/data.txt") or die "Can't open file: $!";



# Store variables and increment access count for this user
# So param('VARIABLE') is the name of the variables used in the HTML form while $custVARIABLE is the input for the database

my($custFirst) = $cgi->param('firstname');
my($custLast) = $cgi->param('lastname');
my($custGender) = $cgi->param('gender');
my($custAge) = $cgi->param('age');
my($custDiv) = $cgi->param('division');
my($custPhone) = $cgi->param('phone');
my($custEmail) = $cgi->param('email');
my($custEmployee) = $cgi->param('employee');
my($custInternet) = $cgi->param('internet');
my($custwww) = $cgi->param('www');
my($custDemographic) = $cgi->param('demographic');
my($custProjects) = $cgi->param('projectsworked');
my($custExperience) = $cgi->param('experience');
my($custWeekdays) = $cgi->param('Weekdays');

#Kept for archival reasons
#my($custName) = $cgi->param('name');
#my($custGender) = $cgi->param('gender');
#my($custDiv) = $cgi->param('division');
#my($custPhone) = $cgi->param('phone');
#my($custEmail) = $cgi->param('email');
#my($custInternet) = $cgi->param('internet');
#my($custwww) = $cgi->param('www');
#my($custDemographic) = $cgi->param('demographic');
#my($custExperience) = $cgi->param('experience');
#my($custTimes) = $cgi->param('times');
#my($custStudies) = $cgi->param('studies');
#$custTimes =~ s/\r\n/~/g;

#This takes the input and places it into an array, starting with the individual's
@InfoDB = $custFirst."|".$custLast."|".$custGender."|".$custAge."|".$custDiv."|".$custPhone."|".$custEmail."|".$custEmployee."|".$custInternet."|".$custwww."|".$custDemographic."|".$custProjects."|".$custExperience."|".$custWeekdays;
print Datastore (@InfoDB);
print "\n";

#Kept for archivival reasons.
#$DB{$custName} = $custGender."|".$custDiv."|".$custPhone."|".$custEmail."|".$custInternet."|".$custwww."|".$custDemographic."|".$custExperience."|".$custTimes."|".$custStudies;

#Kept for archival reasons. dbmclose is de-appreciated
#dbmclose(%DB);
#Instead use untie. But first we're just going experiment with using a flat storage system.
#untie(%DB);
close (Datastore) or die;

#Now inform the person their data has been saved. This is terribly ancient code so I haven't gotten around to fixing this part yet.
print "Content-type: text/html\n\n";

print "<HTML>
<HEAD>
<TITLE>Thank you!</TITLE>
</HEAD>
<BODY>";

print "<H1><U>Thank You ".$custFirst."\!</U></H1>
<P>We appreciate your assistance.</P>
<HR width=\"75%\">";

print "<P><H3>The following information has been recorded:</H3>
Name: <I>".$custFirst."</I></p><P>
Gender: <i>".$custGender."</i></p><p>
Division: <i>".$custDiv."</i></p><p>
Phone: <i>".$custPhone."</i></p><p>
Email: <i>".$custEmail."</I></p><P>
How often do you use the internet?: <i>".$custInternet."</i></p><p>
How often do you visit the website?: <i>".$custwww."</i></p><p>
Are you familiar with demographic data?: <i>".$custDemographic."</i></p><p>
Do you have work experience in economics, business, or a related field?: <i>".$custExperience."</i></p><p>
Weekdays that you are available: <i>".$custWeekdays."</i></p><p>
";

print "
</BODY>
</HTML>";

我进行了一些更改以弥补我正在使用的一些限制。例如,暂时将错误输出到浏览器,直到我得到这个工作。并从旧dbmopen调用(不再有效)转移到平面文件存储。

4

5 回答 5

1

您有以下几行:

# Print the Header
print $cgi->header();

再往下:

#Now inform the person their data has been saved. This is terribly ancient code so I haven't gotten around to fixing this part yet. 
print "Content-type: text/html\n\n";

两者都做同样的事情——你打印相同的内容类型标题两次。您可以删除一个或另一个print呼叫。还可以快速浏览文档header()中的参考资料,了解您可以做的其他事情。CGI.pm

于 2011-04-05T20:27:41.160 回答
1

关于如何从命令行调试 CGI.pm 脚本有几个很好的资源:

我建议你看看这些技术。

于 2011-04-05T20:35:13.373 回答
1

use CGI::Carp qw(fatalsToBrowser) or die "Problems loading CGI.pm";是你的问题。

$ perl -wle 'use CGI::Carp qw(fatalsToBrowser) or die "Problems loading CGI.pm";'
syntax error at -e line 1, near "qw(fatalsToBrowser) or"
Execution of -e aborted due to compilation errors.

你的程序在编译时快死了,所以你没有得到有用的语法错误。通常,您可以在日志中看到这一点,但您不能。语句中的or die是不必要的(并且是语法错误)use。它已经会抛出一个错误。

你真的,真的需要在你的本地机器上工作的 Perl 副本来测试你的程序。将其用作弹药。如果他们仍然不让您拥有工作的工具,请使用不需要安装程序的Strawberry Perl便携式版本。

您还需要访问错误日志。询问管理员。他们可能只允许您访问您的日志,而无需您完全访问服务器。

于 2011-04-05T22:47:46.087 回答
0

此外,作为在黑暗中的粗略刺伤:

open (Datastore, '>>',"E:/intranet/sds/research/docs/data.txt") or die "Can't open file: $!";

我不是 Windows 人,但我认为 Windows 中的路径名使用反斜杠,而不是几乎其他所有人都决定使用的正斜杠。

除了修复print调用之外,您还可以将路径名替换为:

E:\intranet\sds\research\docs\data.txt
于 2011-04-05T21:04:47.707 回答
0

另一个可能与该问题无关的建议,但只是冗余问题:

#!C:\perl\bin\perl.exe -w -t

标志与以下-w内容相同:

use warnings;
于 2011-04-05T21:15:37.757 回答