【问题标题】:Add css for cgi.pm file为 cgi.pm 文件添加 css
【发布时间】:2018-07-18 00:09:09
【问题描述】:

我已经在 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;

【问题讨论】:

  • 检查您的网络服务器的错误日志。
  • 警告:Read the documentation for the CGI module:* CGI.pm 中的所有 HTML 生成功能都不再维护。任何问题、错误或补丁都将被拒绝,除非它们与从根本上破坏的页面渲染有关。*(继续阅读以获取进一步的解释和替代方案)。
  • 警告:Read other bits of the documentation for the CGI module:CGI.pm 不再被认为是开发 Web 应用程序的良好做法,包括快速原型设计和小型 Web 脚本。目前有更好、更清洁、更快、更简单、更安全、更可扩展、更可扩展、更现代的替代方案可用。这些将记录在CGI::Alternatives。
  • @simbabque 加载资源失败:服务器响应状态为 500(内部服务器错误)
  • 为什么use CGI... 有两次?

标签: html css perl cgi.pm


【解决方案1】:

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

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

“Content-Type:”标头应该是绝对从您的 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 个语句意味着代码 printing 和 &lt;div&gt; 发生并且返回值被添加到第一个 print 正在打印的内容列表中。

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

print $q->header;

我真的不知道那乱七八糟的 CGI HTML 代码是什么样子的,所以我不打算尝试修复它,尽管我认为它应该只是一个长的逗号分隔语句.你真的应该看看像模板工具包这样更好的东西。相比之下,即使只是打印出原始 HTML 也更容易阅读 IMO。

此外,为了涵盖所有基础,脚本的第一行似乎在前面有一个空格 - 如果它确实存在并且不仅仅是复制粘贴错误,也会导致问题。

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

【讨论】:

    【解决方案2】:

    您应该了解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 会首先输出什么?字符串“goodbye\n”还是字符串“xxx”?换句话说,打印语句是否等同于:

    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-&gt;header,它返回一个字符串。规则 #2 是:代码中的所有函数调用都替换为函数的返回值。这给了你:

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

    接下来,perl 执行$q-&gt;html,它也返回一个字符串,给你:

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

    最后,评估第三个参数print($q-&gt;div)。第三个参数等价于print("&lt;div&gt;..."),给你:

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

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

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

    现在外部打印终于可以执行了。

    我的服务器使用 Apache,您的 perl 脚本位于此处:

    apache2/cgi-bin/perl2.pl 
    

    获取脚本输出的 url:

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

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

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

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

    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>
    

    请注意,您可以免费获得 head 标签。我认为这是因为标题和链接标签应该在格式良好的 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 =&gt; '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>
    

    【讨论】:

      【解决方案3】:

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

      将您的静态文件移出 cgi-bin 并更改您用来引用它们的 URL 以指向它们的新 URL。

      【讨论】:

      • 我的 cgi 文件在 cgi-bin 中,我将我的 css 文件移到外面并为 css 文件提供了完整正确的路径....仍然存在相同的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-22
      • 2012-07-14
      • 2011-08-06
      • 1970-01-01
      • 2022-08-10
      • 2013-09-08
      相关资源
      最近更新 更多