【问题标题】:CGI::Application, hidden form value overwrittenCGI::Application,隐藏的表单值被覆盖
【发布时间】:2014-03-28 08:13:44
【问题描述】:

我正在查看CGI::Application 的基本示例,但是当我尝试添加第三种模式时,查询对象似乎拒绝使用我提供的值。

webapp.cgi

#!/usr/bin/perl 
  use webapp;
  my $webapp = WebApp->new();
  $webapp->run();

webapp.pm:

package WebApp;
use base 'CGI::Application';

sub setup {
    my $self = shift;
    $self->start_mode('mode1');
    $self->mode_param('rm');
    $self->run_modes(
        'mode1' => 'do_stuff',
        'mode2' => 'do_more_stuff',
        'mode3' => 'do_something_else'
        );
}


sub do_stuff {
    my $self = shift;
    my $q = $self->query();

    my $output = '';
    $output .= $q->start_html(-title => 'Widget Search Form');
    $output .= $q->start_form();
    $output .= $q->textfield(-name => 'widgetcode');
    $output .= $q->hidden(-name => 'rm', -value => 'mode2');
    $output .= $q->submit();
    $output .= $q->end_form();
    $output .= $q->end_html();

    return $output;
}

sub do_more_stuff {
        my $self = shift;
        my $q = $self->query();
        my $widgetcode = $q->param("widgetcode");
        my $output = '';
        $output .= $q->start_html(-title => 'List of Matching Widgets');    
        $output .= $q->start_form();
        $output .= $q->textfield(-name => 'widgetcode');
        $output .= $q->hidden(-name => 'rm', -value => 'mode3'); 
                                                     # ^^^^^^ 
                                                     # this value is being ignored
        $output .= $q->submit();
        $output .= $q->end_form();      
        $output .= $q->end_html();

        return $output;
}

sub do_something_else {
        my $self = shift;
        my $q = $self->query();
        my $widgetcode = $q->param("widgetcode");
        my $output = '';
        $output .= $q->start_html(-title => 'Widgets details');  
        $output .= $q->start_form();
        $output .= $q->textfield(-name => 'widgetcode');
        $output .= $q->hidden(-name => 'rm', -value => 'mode4');
        $output .= $q->submit();
        $output .= $q->end_form();
        $output .= $q->end_html();
        return $output;
}

1;

所以加载第一页(模式1)工作正常,它给了我表单,我可以提交它并到达第二页(模式2),但我无法到达模式3,因为rm参数正在设置为“mode2”,尽管正如您在上面看到的那样,我将其设置为“mode3”。这意味着我再次被送回模式 2。我可以将rm 更改为rm2 或其他内容,然后获取正确的值,但这显然没有帮助,因为rm 变量是用于设置模式的。

我没有使用 CGI.pm(它提供 query 对象)的经验,正如您所知,我才刚刚开始学习 CGI::Application,所以我不知道发生了什么或者如何解决这个问题。

【问题讨论】:

  • 请注意,模块的包和文件名必须在 Linux 机器上相同,并且在 Windows 上遵循该约定也是如此。所以文件应该是WebApp.pm,包应该是WebApp,你应该是use WebApp,并用my $webapp = WebApp->new创建一个新对象
  • 嗨 Borodin,这个 is 在 linux 机器上,是的,我知道惯例,我只是碰巧在意识到我没有大写之前保存了它一样的方法。由于它有效,而且只是为了测试示例代码,我并没有真正打扰。无论如何感谢您的提醒。

标签: perl cgi


【解决方案1】:

看来perlmonks有智慧:Hidden fields using CGI

您可以使用 -override 参数强制它使用默认值。

在我的情况下将按如下方式使用:

$output .= $q->hidden(-name => 'rm', -value => 'mode3' , -override => 1);

希望对通过搜索找到此问题的人有所帮助,因为这根本不明显。

【讨论】:

    【解决方案2】:

    是的,hidden 方法似乎将使用当前表单值(如果存在)而不是您指定的默认值。在使用?rm=mode2 访问视图时,可以使用以下代码观察到这一点:

    $output .= $q->hidden(-name => 'rm', -value => 'mode3'); # Prints mode2
    $q->param('rm' => 'mode3');
    $output .= $q->hidden(-name => 'rm'); # Print mode3
    

    如您所见,最好的解决方案是使用 CGI #Form Elements 中记录的覆盖标志

    $output .= $q->hidden(-name => 'rm', -value => 'mode3', -override => 1); # Print mode3
    

    【讨论】:

    • 这是设计使然。对于大多数表单字段,您希望能够指定默认值,但如果用户在提交后停留在同一页面上,您希望字段自动填充用户提供的数据。隐藏字段被视为与一些结转相同。很难说首选逻辑应该是什么,但认识到所有表单字段都被同等对待可能会简化事情。所以只需要记住覆盖标志。
    • 嗯,这很奇怪,这对初学者来说无疑是一个绊脚石,并且增加了对采用的阻力。我可以预见将来会再次被这个咬。感谢您的信息。
    • 实际上,我希望它很少出现。事情就是这样,他们建议的例子有点做作。大多数编码人员将在与表单相同的“模式”上对表单进行验证。如有必要,您希望仍能显示带有错误消息的原始表单。只有在确认成功后,您才会进入新的“模式”或形式。因此,这个示例简化了事情以在不同模式下进行验证的事实很少发生,并且这样做只是为了向您展示不同模式的概念。不是为了展示良好的编码实践。
    • 啊,我想我明白你的意思了。我将不得不更多地了解它是如何工作的,以正确理解这里的行为选择。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多