Perl:从多个提交按钮重定向 CGI

Perl: CGI redirect from multiple submit buttons

我有一个带有 2 个提交按钮的小型 CGI 脚本。我希望当前脚本将用户重定向到另一个脚本,具体取决于按下的提交按钮。

CGi 脚本:

#!/usr/bin/perl -w

# Modules
use strict;
use warnings;
use CGI;

my $q                           = CGI->new();
print $q->header();
print $q->submit(-name=>'button',-value => 'disable');
print $q->submit(-name=>'button',-value => 'enable');

if ($q->param('button') eq "disable"){
         print $q->redirect(-uri=>"http://1.1.1.1./cgi-bin/services/switch_XXX.cgi?disable");
} elsf ($q->param('button') eq "enable"){
        print $q->redirect(-uri=>"http://1.1.1.1./cgi-bin/services/switch_XXX.cgi?enable");
} else {
}

但实际执行了 none 个操作。错误日志显示以下内容:

[Tue Mar 06 11:48:44 2018] [error] [client XXXX] Use of uninitialized value in string eq at /var/www/cgi-bin/test.cgi line 23.
[Tue Mar 06 11:48:44 2018] [error] [client XXXX] Use of uninitialized value in string eq at /var/www/cgi-bin/test.cgi line 26.

你们谁能告诉我是什么原因导致错误以及为什么重定向不起作用?

非常感谢!

请参阅 CGI 文档中的 "Generating a redirection header":"If you use redirection like this, you should not print out a header as well."

您在日志中看到的消息是指 $q->param('button') eq "disable" 检查:$q->param('button') 正在返回 undef 因为该字段尚未提交,所以您将 "disable" 与未定义的值进行比较。这些只是警告消息,您可以通过在进行 eq 比较之前首先检查 $q->param('button') 是否具有真值来避免这些消息。 (注意:在其他情况下,可能想使用 defined to check for undef, because there are some values in Perl that are defined but still false, see Truth and Falsehood - 但在这种情况下,"disable""enable" 都是真值。)

此外,您的提交按钮需要位于 <form> 中。请注意,您有一个 elsf 的拼写错误。这对我有用:

#!/usr/bin/env perl
use strict;
use warnings;
use CGI;

my $q = CGI->new();
if ( $q->param('button') && $q->param('button') eq "disable" ) {
    print $q->redirect(-uri=>"...");
} elsif ( $q->param('button') && $q->param('button') eq "enable" ) {
    print $q->redirect(-uri=>"...");
} else {
    print $q->header();
    print $q->start_html;
    print $q->start_form;
    print $q->submit(-name=>'button', -value=>'disable');
    print $q->submit(-name=>'button', -value=>'enable');
    print $q->end_form;
    print $q->end_html;
}

如果您刚开始用 Perl 编写 Web 应用程序,我建议您阅读 CGI::Alternatives 并决定您是否真的想在更新更好时使用这种旧技术(并且仍然 Perl-based) 有替代品。

但是,如果您决定坚持使用 CGI(和 CGI.pm),那么有几件事可以让您的生活更轻松。

难得需要两个CGI对象的CGI程序

对于大多数 CGI 程序,使用 object-oriented 方法是多余的。你很少需要对象。 CGI.pm 有一个更简单的 function-based 方法,您可以改用它。简单地,在加载模块时导入要使用的函数:

use CGI qw[param header redirect];

然后在不创建对象的情况下使用它们:

if (param) {
  print redirect(...);
} else {
  print header(...);
}

CGI-Generation 函数是个糟糕的主意

甚至in the documentation

HTML Generation functions should no longer be used

All HTML generation functions within CGI.pm are no longer being maintained. Any issues, bugs, or patches will be rejected unless they relate to fundamentally broken page rendering.

The rationale for this is that the HTML generation functions of CGI.pm are an obfuscation at best and a maintenance nightmare at worst. You should be using a template engine for better separation of concerns. See CGI::Alternatives for an example of using CGI.pm with the Template::Toolkit module.

These functions, and perldoc for them, are considered deprecated, they are no longer being maintained and no fixes or features for them will be accepted. They will, however, continue to exist in CGI.pm without any deprecation warnings ("soft" deprecation) so you can continue to use them if you really want to. All documentation for these functions has been moved to CGI::HTML::Functions.

将您的 HTML 放入外部模板是一个更好的主意。您的 front-end 开发人员可以更轻松地进行编辑。是的,我知道您的项目现在可能没有 front-end 开发人员 - 但您不想提前计划吗?

话虽如此,你的程序变成了这样:

#!/usr/bin/perl

use strict;
use warnings;
use CGI qw[param header redirect];

my $disable_url = '...';
my $enable_url  = '...';

if (param('button') {
  if (param('button') eq 'disable') {
    print redirect($disable_url);
  } elsif (param('button') eq 'enable') {
    print redirect($enable_url);
  }
  exit;
} 

print header;
print $some_output_that_is_generated_from_a_template.