我已经在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;
答案 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
之外,并更改用于引用它们的网址以指向新网址。