【问题标题】:Upload a file using HTML and Perl使用 HTML 和 Perl 上传文件
【发布时间】:2012-10-04 21:57:53
【问题描述】:

我正在尝试简单上传 .csv 文件并将其保存在我的服务器上。我不是 HTML 或 Perl 方面的专家,但由于客户端的限制,这是我必须做的。

这是 HTML:

<form action="/path/to/service" target="_self" method="POST" enctype="multipart/form-data">
File: <input type="file" name="attachment" size="50">
<SUBMIT_RESET Upload File>
</form>

Perl 代码如下所示:

    my $sql = "SELECT NOW()";
    my $date = $DB->get_field($sql);

    my ($path, $ext) = split(/\./, $in{'attachment'});
    my @pathParts = split(/\//, $path);            
    my $filename = $pathParts[@pathParts - 1] . " - " . $date;

    if ($ext eq "csv") {                

        open (OUTFILE, ">", "$datadir/imports/" . $filename . "." . $ext);

        while (read($in{'attachment'}, $buffer, 1024)) {
            $file .= $buffer;
        }
        print OUTPUT $file;
        close (OUTFILE);
    }

谁能给我一些关于我做错了什么的指导。我得到了位于正确路径的文件,但它总是空的。

现在,我在这里处理的代码库很糟糕,我不能使用 strict。

建议?

编辑1: 为了尝试回答 $in{'attachment'} 是如何填充的,我包含了一个关于如何处理表单的代码的 sn-p。

如果 ($ENV{'CONTENT_TYPE'} =~ m#^multipart/form-data#) {
我的 $cgi = 新的 CGI; 我的@names = $cgi->param;

        foreach $name (@names) {
            my @value = $cgi->param($name);
            if (scalar(@value) > 1) {
                foreach $val (@value) {
                    $in{$name} .= $val."\0";
                }
                $in{$name} =~s/\\0$//;
            } else {
                my $value = $cgi->param($name);
                #my $value = join "\0", @value;
                $in{$name} = $value;
            }
            #my $value = $cgi->param($name);
            #my $value = join "\0", @value;
            #$in{$name} = $value;
        }

EDIT2:

总结一下ikegami提供的解决方案...

我错过了读取和打印语句的文件句柄不同 - OUTFILEOUTPUT。显然这完全是一个新手错误,对此我深表歉意!

向所有试图帮助我的人致以最良好的祝愿。

【问题讨论】:

  • $in{'attachment'} 是如何填充的?
  • 我假设 $in{'attachment'} 是读取附件的文件句柄。尝试将其放在任何读取之前。 binmode $in{'attachment'};
  • @Robert Hanson,Rico 也可以假设相同。
  • 您可以在块 ({ use strict; ... }) 中使用严格,包括在子 (sub foo { use strict; ... }) 中,而不会影响它周围的任何东西。
  • $in{'attachment'} 是如何填充的? 特别!你没有提供你的意见,问题是你的意见。

标签: html perl cgi


【解决方案1】:

您不应该使用全局变量。如果您的文件句柄是词法变量(自 2000 年以来受支持!)并且您一直在使用 use strict;(自 2000 年以来也受支持,如果不是更早的话!),您就会发现问题:

您在print 调用中没有使用正确的变量。

open (OUTFILE, ">", "$datadir/imports/" . $filename . "." . $ext);
print OUTPUT $file;

当我发现问题时,我正要建议你找出你实际遇到的错误:

open(my $OUTFILE, ">", "$datadir/imports/$filename.$ext")
   or die $!;

while (1) {
   my $rv = read($in{'attachment'}, my $buf, 1024);
   die $! if !defined($rv);
   last if !$rv;

   print $OUTFILE $buf
      or die $!;
}

close($OUTFILE)
   or die $!;

(我假设错误是“Bad file descriptor”,因为将不是文件句柄的东西传递给了read。)

【讨论】:

  • 完全错过了分配的文件句柄。谢谢!
【解决方案2】:

HTML 代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title>File Upload</title> 
</head> 
<body> 
    <form action="upload.cgi" method="post" enctype="multipart/form-data"> 
        <p>Photo to Upload: <input type="file" name="photo" /></p> 
        <p><input type="submit" name="Submit" value="Submit Form" /></p> 
    </form> 
</body> 
</html>

Perl Code下文件名为upload.cgi:

#!C:\Program Files\perl\bin\perl.exe

use strict; 
use CGI; 
use CGI::Carp qw ( fatalsToBrowser ); 
use File::Basename; 
$CGI::POST_MAX = 1024 * 5000; 
my $safe_filename_characters = "a-zA-Z0-9_.-"; 
my $upload_dir = "fileUpload/"; 
my $query = new CGI; my $filename = $query->param("photo"); 
if ( !$filename ) 
{ 
    print $query->header ( ); 
    print "There was a problem uploading your photo (try a smaller file)."; 
    exit; 
} 
my ( $name, $path, $extension ) = fileparse ( $filename, '..*' ); 
$filename = $name . $extension; 
$filename =~ tr/ /_/; $filename =~ s/[^$safe_filename_characters]//g; 
if ( $filename =~ /^([$safe_filename_characters]+)$/ ) 
{ 
    $filename = $1; 
} else { 
    die "Filename contains invalid characters"; 
} 
my $upload_filehandle = $query->upload("photo"); 
open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!"; 
binmode UPLOADFILE; 
while ( <$upload_filehandle> ) 
{ 
    print UPLOADFILE; 
} 
close UPLOADFILE;
print $query->header ( ); 
print <<END_HTML; 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Thanks!</title> 
<style type="text/css"> 
img {border: none;} 
</style> 
</head> 
<body> 
<p>Thanks for uploading your photo!</p> 
</body> 
</html> 
END_HTML

这段代码不是我写的,但对我有很大帮助。我希望它也能帮助你。使这段代码对我有用的原因是正确地找到了 perl.exe 的路径。

【讨论】:

    猜你喜欢
    • 2012-12-17
    • 1970-01-01
    • 2016-05-08
    • 2011-08-12
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 2020-05-02
    相关资源
    最近更新 更多