为cgi.pm文件

时间:2018-02-07 16:05:44

标签: html css perl cgi.pm

我已经在html的cgi文件中编写了这段代码,但它在xampp服务器中显示了内部服务器错误。当我在命令行中编译它时,它只是显示'无调试'作为结果。我做错了什么?代码工作正常,没有包含css部分,但是一旦我添加了链接部分,它就会停止工作。

 #!"c:\xampp\perl\bin\perl.exe"
use strict;
use warnings;
use CGI qw(:all); 
use CGI::Carp qw(fatalsToBrowser);
#use CGI ('div');
use CGI qw/Link/;

my $q = new CGI;

print $q->header,

$q->start_html
({
  -title=>'Input Request',
  -head=>Link({-rel => 'stylesheet', 
                        -media  => 'print',
                        -type   => 'text/css',
                        -href   => 'style.css'}), 

}),

print $q->div(
              {-id=>"divtop"},
              $q->p("Here's a paragraph")
             );
$q->start_form
(
    -method=>'post',
    ), "\n",

    "Operating System",

    $q->radio_group
    (
    -name=>'ostype',
    -values=>['Windows','Linux'],
    ),
    $q->br, "\n",
$q->end_html;

3 个答案:

答案 0 :(得分:3)

运行代码后问题非常明显。这是它输出的第一行...

<div id="divtop"><p>Here's a paragraph</p></div>Content-Type: text/html; charset=ISO-8859-1

&#34;内容类型:&#34;标题应该是绝对从CGI脚本中产生的第一件事。其他任何内容和您的网络服务器都不知道如何处理输出。

您的代码中的分号和逗号之间似乎很混淆

print $q->header,

$q->start_html
({
  -title=>'Input Request',
  -head=>Link({-rel => 'stylesheet', 
                        -media  => 'print',
                        -type   => 'text/css',
                        -href   => 'style.css'}), 

}),

print $q->div(
              {-id=>"divtop"},
              $q->p("Here's a paragraph")
             );

使用逗号链接这3个语句意味着代码print发生了<div>,并且返回值被添加到第一个print打印的事物列表中。

整理一下,你的代码看起来应该是这样的。标题行首先出现,只是单个语句本身。

print $q->header;

我真的不知道那些混乱的CGI HTML代码是什么意思,所以我不打算尝试修复它,虽然我认为它应该只是一个长逗号分隔的陈述。你应该真正看看像Template Toolkit这样的东西。相比之下,即使只是打印出原始HTML也会更容易阅读IMO。

此外,为了覆盖所有基础,您的脚本的第一行似乎在前面有一个空格 - 如果它实际存在也会导致问题并且不仅仅是副本&#39; n&#39 ;粘贴错误。

 #!"c:\xampp\perl\bin\perl.exe"

答案 1 :(得分:1)

您应该了解print(或任何其他功能的工作原理):

1)以下是一个例子:

use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;
use DBI;

sub do_stuff {
    print "xxx\n";
}

print "goodbye\n", do_stuff, "\n";

您认为perl首先会输出什么?字符串&#34;再见\ n&#34;或字符串&#34; xxx&#34;?换句话说,print语句是否相当于:

print "goodbye\n";
print dostuff;
print "\n";

???

2)以下是另一个例子:

print "hello", die("Too tired too print anything else...");

您认为产量是多少? die()会导致程序立即终止并在退出前输出指定的消息。

The rule是:在函数本身执行之前,必须完全确定函数的参数。因此,在您编写的perl脚本中:

print $q->header,

...这是正确的,因为你必须先输出响应头。但那后面有逗号。您继续使用以下语言打印声明:

print $q->header, $q->start_html(), print $q->div() 

该陈述相当于:

print(
    $q->header,
    $q->start_html(),
    print($q->div)
)

好的,应用规则:外部print()不会执行,直到确定了三个参数中的每一个。因此,perl执行$q->header,返回一个字符串。规则#2是:代码中的所有函数调用都被函数的返回值替换。这给了你:

print(
    "some http response info,
    $q->start_html()
    print($q->div)
)

接下来,perl执行$q->html,它还会返回一个字符串,为您提供:

print(
    "some http response info",
    "<html> blah blah",
    print($q->div)
)

最后,评估第三个参数print($q->div)。第三个参数相当于print("<div>..."),给你:

print(
    "some html response stuff",
    "<html> blah blah",
    print("<div...")
)

正如我在答案开头的前两个例子所示,内部print()将在外部打印能够打印前两个参数之前执行。因此,您最终不会首先输出标题,因此您的错误。 print("<div...")在输出字符串后实际返回1,因此最终得到:

print(
    "some html response stuff",
    "<html> blah blah",
    1
)

现在外部印刷品最终可以执行。

我使用Apache作为我的服务器,你的perl脚本位于:

apache2/cgi-bin/perl2.pl 

检索脚本输出的网址:

http://localhost:8080/cgi-bin/perl2.pl

我在这里放了一个css文件:

apache2/cgi-bin/htdocs/css/my.css

通常,我可以在htdocs中检索html页面而不指定htdocs目录,所以:

http://localhost:8080/page.html

因此,从cgi-bin目录到htdocs目录中的文件的路径很简单:

../css/my.css  (rather than ../htdocs/css/my.css)

您的代码包含访问css文件所需的所有更改:

use strict;
use warnings;
use CGI qw(:all); 
use CGI::Carp qw(fatalsToBrowser);

my $q = new CGI;

print(

    $q->header,

    $q->start_html(
        -title => 'Input Request',
        -style=>{-src=>"../css/my.css"}    #<==THIS CREATES A LINK TAG           
    ),

    $q->div(
        {-id=>"divtop"},
        $q->p("Here's a paragraph")
    ),

    $q->start_form(
        -method=>'post'
    ),

    $q->div("OperatingSystem"),
    $q->div(
        $q->radio_group(
            -name=>'ostype',
            -values=>['Windows','Linux']
        )
    ),

    $q->end_form,
    $q->end_html
);

这里是perl脚本创建的html(由我调整的间距):

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">

<head>
  <title>Input Request</title>
  <link rel="stylesheet" type="text/css" href="../css/my.css" />
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>

<body>

<div id="divtop"><p>Here's a paragraph</p></div>

<form method="post" action="/cgi-bin/perl2.pl" enctype="multipart/form-data">
  <div>OperatingSystem</div>
  <div>
    <label><input type="radio" name="ostype" value="Windows" checked="checked" />Windows</label> 
    <label><input type="radio" name="ostype" value="Linux" />Linux</label>
  </div>

<div><input type="hidden" name=".cgifields" value="ostype"  /></div>
</form>

</body>
</html>

请注意,您可以免费获得头标记。我认为这是因为标题和链接标签应该在格式良好的html中的head标签内。

而且,这里使用的是Link()

print(

    $q->header,

    $q->start_html(
        -title => 'Input Request',
        -head  => Link({
                   -rel    => 'stylesheet',
                   -type   => 'text/css',
                   -href   => '../css/my.css'
                  })    
    ),

    $q->div(
        {-id=>"divtop"},
        $q->p("Here's a paragraph")
    ),

    $q->start_form(
        -method=>'post'
    ),

    $q->div("OperatingSystem"),
    $q->div(
        $q->radio_group(
            -name=>'ostype',
            -values=>['Windows','Linux']
        )
    ),

    $q->end_form(),

    $q->br(),
    $q->end_html()

);

如果我将media => 'print添加到Link()哈希,这会将属性media="print"添加到链接标记,则会在浏览器中禁用css。另一方面,当我在浏览器中对页面进行打印预览时,我确实看到了css样式。我认为这是预期的行为。这是html:

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">

<head>
<title>Input Request</title>
<link type="text/css" rel="stylesheet" href="../css/my.css" />
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>

<body>
<div id="divtop"><p>Here's a paragraph</p></div><form method="post" action="/cgi-bin/perl2.pl" enctype="multipart/form-data"><div>OperatingSystem</div><div><label><input type="radio" name="ostype" value="Windows" checked="checked" />Windows</label> <label><input type="radio" name="ostype" value="Linux" />Linux</label></div><div><input type="hidden" name=".cgifields" value="ostype"  /></div></form><br />
</body>
</html>

答案 2 :(得分:0)

CGI程序通常放在cgi-bin目录中,该目录的配置使Web服务器将中的所有视为符合CGI的可执行文件。您的CSS文件不是可执行的CGI程序!

移动静态文件 cgi-bin之外,并更改用于引用它们的网址以指向新网址。