如何使用CGI Perl Script在xampp apache服务器上上传和打开文件?

时间:2014-08-18 11:38:42

标签: apache perl cgi

此代码在我的本地xampp apache服务器中正常运行。我在局域网中使用不同的ip寻址系统运行相同的代码。该文件无法打开,我无法将其写入预期的目录。请做必要的吗?提前谢谢。

通过以下代码传递xml文件。

#!"C:\xampp\perl\bin\perl.exe"
#!"172.18.5.23:\xampp\perl\bin\perl.exe"
#!\usr\bin\perl -wT
#!perl
use strict;
use warnings;
use CGI;
my $query = new CGI;
print $query->header( "text/html" );
print <<END_HERE;


 <html>
      <head>
        <title>My First CGI Script</title>
      </head>
      <body bgcolor="#FFFFCC">
        <h1>Welcome to Perl CGI</h1>
        <form action="/cgi-bin/inputxml.cgi" method="post"
        enctype="multipart/form-data">
        <p>Files to Upload: <input type="file" name="xml" /></p>
        <p><input type="submit" name="Submit" value="Submit Form" /></p>
        </form>
      </body>
    </html>
    END_HERE

将xml文件发送到以下代码.....

#!"C:\xampp\perl\bin\perl.exe"
    #!"172.18.5.23:\xampp\perl\bin\perl.exe"
    #!\usr\bin\perl -wT
    #!perl
    use strict;
    use CGI;
    use Cwd 'abs_path';
    use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
    use File::Basename;
    $CGI::POST_MAX;
    my $safe_filename_characters = "a-zA-Z0-9_.-";
    my $query = new CGI;
        my $cgi = new CGI;
        my $file = $cgi->param('xml');
        my $lines;
        open(DATA,"<$file") or die "Can't open data";
        print $query->header ( );
        $lines = <DATA>;
        close(DATA);
        $lines =~s{darling}{CGI}ig;
        print $lines;
        print abs_path($file);
        open(OUT, '>dirname($file)."\\out_".basename($file)');
        print OUT $lines;
        close(OUT);


        print $query->header ( );
    print <<END_HERE;

1 个答案:

答案 0 :(得分:4)

从输入参数获取文件名(在本例中为“xml”)总是一个非常糟糕的主意。浏览器的行为不同。有些给你完整的文件名,有些只给你基本名称。当他们为您提供完整路径时,它将是客户端计算机上的路径 - 几乎保证您的服务器上不存在该路径。 [更新:重新阅读您的问题,我意识到这正是您在本地测试时的原因。]

explanation of how to do this的文档中有一个详细的CGI module。在编写代码之前,您应该真正阅读该部分的所有内容。但总的来说。

# Get the filename which may well include a path and which
# should never be used as a filename on the server.
my $filename = $cgi->param('xml');

# Try to calculate a local filename
my $local_fn;
if ($filename =~ /([-\w\.]+)$/) {
  $local_fn = $1;
}

# Get file handle to uploaded file
my $local_in_fh = $cgi->upload('xml');

# Open a file handle to store the file
open $local_out_fh, '>', "/path/to/output/dir/$local_fn" or die $!;

while (<$local_in_fh>) {
  # process one line from the input file (which is in $_)
  print $local_out_fh;
}

还有一些其他可能对您有用的事情。

$cgi->uploadInfo($filename)->{'Content-Type'}会为您提供上传文件的MIME类型。您可以使用它来计算出如何处理文件。

$cgi->tmpFileName($filename)将为您提供上传数据的临时文件的路径。当CGI程序退出时,这将被删除。但是,如果您只想保存文件而不以任何方式处理它,您只需将此文件移动到服务器上的新位置即可。

关于您现有解决方案的其他一些说明:

  1. 您的第一个程序只显示一个HTML文件。那么为什么不使用静态HTML文件呢?
  2. $CGI::POST_MAX什么也没做。
  3. 请使用CGI->new代替new CGI
  4. 您创建了两个CGI对象($query$cgi)。你只需要一个。
  5. 您打印两次CGI标题。
  6. DATA是一个特殊的文件句柄名称。您不应将它用于自己的文件句柄。
  7. $lines = <DATA>只会从文件中获取第一行。
  8. open(OUT, '>dirname($file)."\\out_".basename($file)')没有像你认为的那样做任何事情。