Reputation: 121
I have a small CGI Script with 2 submit buttons. I want that the current Script redirects the User to another script, depending on which submit button is pressed.
The CGi-Script:
#!/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 {
}
But none of the actions is actually performed. The Error-Log shows the following:
[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.
Could someone of you tell me what causes the error and why the redirect is not working?
Many thanks in advance!
Upvotes: 1
Views: 828
Reputation: 69274
If you are just starting to write web applications in Perl, I would urge you to read CGI::Alternatives and decide whether you really want to use such old technology when newer and better (and still Perl-based) alternatives are available.
However, if you decide to stick with CGI (and CGI.pm) then there are a couple of things that can make your life easier.
It's a rare CGI program that needs two CGI objects
For most CGI programs, using an object-oriented approach is overkill. You rarely need objects. CGI.pm has a, simpler, function-based approach that you can use instead. Simply, import the functions that you want to use as you load the module:
use CGI qw[param header redirect];
Then use them without creating an object first:
if (param) {
print redirect(...);
} else {
print header(...);
}
The CGI-Generation functions are a terrible idea
It's even 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.
Putting your HTML into an external template is a much better idea. And it will be easier for your front-end developer to edit. Yes, I realise you probably don't have a front-end developer on your project right now - but don't you want to plan ahead?
Having said that, your program becomes something like this:
#!/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.
Upvotes: 2
Reputation: 3013
See "Generating a redirection header" in the CGI docs: "If you use redirection like this, you should not print out a header as well."
The messages you're seeing in the log are referring to the $q->param('button') eq "disable"
checks: $q->param('button')
is returning undef
because the field has not been submitted yet, so you're comparing "disable"
to the undefined value. These are warning messages only, that you can avoid by first checking if $q->param('button')
has a true value before doing the eq
comparison. (Note: In other cases, one might want to use defined
to check for undef
, because there are some values in Perl that are defined but still false, see Truth and Falsehood - but in this case, both "disable"
and "enable"
are true values.)
Also, your submit buttons need to be in a <form>
. And note you've got a typo with elsf
. This works for me:
#!/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;
}
Upvotes: 3