使用HTML和Perl上传文件
问题描述:
我正在尝试简单地上载.csv文件并将其保存在我的服务器上。我不是HTML或Perl方面的专家,但由于客户的限制,这是我必须做的。使用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);
}
任何人都可以请给我一些指导,以什么我做错了。我得到的文件位于正确的路径,但它总是空的。
现在,我在这里处理的代码基础是可怕的,我不能严格使用。
对此提出建议?
EDIT1: 要试图回答{'attachment'}中的$是如何填充的,我已经包含了如何处理表单的一段代码。
if($ ENV {'CONTENT_TYPE'} =〜m#^ multipart/form-data#){
my $ cgi = new CGI; my @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:
总结池上所提供的解决方案......
我错过了的文件句柄是用于读取和打印语句不同 - OUTFILE
和OUTPUT
。很明显,这完全是一个新手的错误,为此我表示歉意!
对所有试图帮助我的人表示最良好的祝愿。
答
你不应该使用全局变量。如果你的文件句柄是词法变量(自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
)。
答
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代码文件名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的路径。
'$ in {'attachment'}'是如何填充的? – ikegami
我假设$ {'attachment'}中的$是读取附件的文件句柄。尝试之前任何读取。 binmode $ in {'attachment'}; –
@Robert Hanson,它也可以是Rico。 – ikegami