【问题标题】:Perl: CGI redirect from multiple submit buttonsPerl:来自多个提交按钮的 CGI 重定向
【发布时间】:2018-08-14 05:04:12
【问题描述】:

我有一个带有 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 {
}

但实际上并没有执行任何操作。错误日志显示如下:

[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.

谁能告诉我导致错误的原因以及重定向不起作用的原因?

非常感谢!

【问题讨论】:

  • 你的输出和表单处理代码混在一起了
  • 加上你输出的 HTML 也不完整
  • @ChrisTurner 我只想为多个提交按钮分配不同的操作..

标签: perl cgi url-redirection


【解决方案1】:

请参阅 CGI 文档中的 "Generating a redirection header":“如果您像这样使用重定向,您应该也打印出标题。”

您在日志中看到的消息指的是 $q->param('button') eq "disable" 检查:$q->param('button') 正在返回 undef,因为该字段尚未提交,因此您将 "disable" 与未定义的值进行比较.这些只是警告消息,您可以通过在进行eq 比较之前首先检查$q->param('button') 是否具有真值来避免这些消息。 (注意:在其他情况下,可能需要使用defined 来检查undef,因为Perl 中有一些值已定义但仍然为假,请参阅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;
}

【讨论】:

  • 非常感谢!得到它的工作。我认为需要检查 if 语句中的两个按钮 $q->param('button') && $q->param('button') 有点令人困惑。但只要它的工作。
  • 您可以使用例如缩短该代码my $btn = $q->param('button') || ''; if ( $btn eq "disable" ) { ... } elsif ( $btn eq "enable" ) { ...(与错误但定义的值相同的问题也适用;另请参阅defined-or //
【解决方案2】:

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

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

这是一个罕见的需要两个 CGI 对象的 CGI 程序

对于大多数 CGI 程序,使用面向对象的方法是多余的。你很少需要对象。 CGI.pm 有一种更简单、基于函数的方法,您可以使用它。只需在加载模块时导入您想要使用的函数:

use CGI qw[param header redirect];

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

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

CGI 生成函数是个糟糕的主意

甚至是in the documentation

不应再使用 HTML 生成函数

所有 HTML 生成 CGI.pm 中的功能不再被维护。任何问题, 错误或补丁将被拒绝,除非它们从根本上涉及 页面渲染损坏。

这样做的理由是 CGI.pm 的 HTML 生成功能 充其量是一种混淆,最坏的情况是维护的噩梦。你 应该使用模板引擎来更好地分离关注点。 有关使用 CGI.pm 的示例,请参阅 CGI::Alternatives Template::Toolkit 模块。

这些函数以及它们的 perldoc 被认为已弃用,它们 不再维护,并且不会为他们提供任何修复或功能 被接受。但是,它们将继续存在于 CGI.pm 中,而无需 任何弃用警告(“软”弃用),以便您可以继续 如果你真的想使用它们。这些功能的所有文档 已移至CGI::HTML::Functions

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

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

#!/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.

【讨论】:

  • 太棒了!当我的同事说构建一个 cgi 程序时,他们无法理解。它已被弃用且效率低下。谢谢,我会查找你的 cgi 替代品。!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
  • 2013-07-06
  • 1970-01-01
相关资源
最近更新 更多