CGI上传创建空文件

时间:2012-09-14 11:59:19

标签: perl upload cgi

您好我正在尝试使用CGI上传文件,虽然运行了CGI脚本,但创建的文件为空。

我有一个html文件,它获取文件名并将其传递给cgi脚本:

<html>
<body>

<form enctype="multipart/form-data" action="cgi-bin/upload.pl" method="POST">
<input type="FILE" name="file">
<input type="submit">
</form>

</body>
</html>

cgi脚本如下:

#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use CGI;

print "Content-type: text/html\n\n";

my $cgi = new CGI;
my $dir = 'sub';

my $name = $cgi->param('file');
print "name: $name <br />\n";
open(LOCAL, ">$dir/$name") or die "error: failed to open $dir/$name\n";
my $file_handle = $cgi->upload('file');
die "file_handle not defined\n" unless(defined($file_handle));
while(<$file_handle>) {
    print $_;
    print LOCAL $_;
}
close($file_handle);
close(LOCAL);

print "done\n";

cgi脚本运行正常,不产生警告,设法创建本地文件并正确获取远程文件名。但是,脚本似乎不会从文件中读取任何数据或将任何数据写入本地文件,该文件为空。

我肯定会上传一个包含多行数据的文件,但cgi脚本的输出如下:

   name: tmp.txt 
   done

任何帮助都非常感谢...

1 个答案:

答案 0 :(得分:0)

您可能想尝试在FH上使用binmode命令。

这是一个Perl脚本,我用它作为上传文件的CGI表单的起点(显示表单上传):

#!/usr/bin/perl

use strict;
use warnings;

use POSIX;
use CGI::Pretty qw(:standard -any -no_xhtml -oldstyle_urls *center);
use CGI::Carp qw(fatalsToBrowser set_message);

use Upload;

# Constants
my $FILE_DIR_INTERNAL = 'Z:\webroot\tmp';

# Variables
my $ACTION = param('action') || "";

if (! $ACTION) { UploadForm() }
elsif ($ACTION eq "UploadFile") {
  my $file = UploadFile($FILE_DIR_INTERNAL, 1);
  print "File uploaded to $file\n<pre>";
  open(F, "$file");
  while(<F>) { print }
  close(F);
}

这是该脚本使用的Perl模块:

package Upload;

use strict;
use warnings;
use POSIX;
use File::Copy;
use CGI::Pretty qw(:standard -any -no_xhtml -oldstyle_urls *center);
use CGI::Carp qw(fatalsToBrowser); # supposed to echo STDERR to browser, too

use Exporter;
our $VERSION = do{ q$Revision: 1.5 $ =~ /(\d+)\.(\d*)([^ ]*)/; sprintf "%d.%02d%s", $1, $2, $3; };
our @ISA = qw(Exporter);
our @EXPORT = qw(UploadForm UploadFile);


my $FILE_UPLOAD_PARAM = "fileUploaded";

# *************************************************************************
# FUNCTION: UploadForm
# ARGUMENTS:    
# RETURNS:  
# NOTES:    This subroutine displays the upload form.
# *************************************************************************
sub UploadForm {


  print start_center;
  print p("Upload a file from your computer:");

  # Normally, I use the "get" method for forms (params show up in URL),
  # but "post" is required for uploading files!
  # Using "post" also requires that we pass parameters thru the hidden()
  # commands down below, instead of in the URL.
  print start_multipart_form({-method=>"post", -action=>script_name});
  print filefield($FILE_UPLOAD_PARAM,"",50) . "\n";

  # Hidden parameters are "sticky", so modify the existing "action" param,
  # before trying to insert a new hidden "action" param.
  # If you don't, CGI.pm will re-use the current "action" param.
  param("action", "UploadFile");
  print hidden("action") . "\n";

  print p(submit("", "Upload File"));
  print end_form;

  print end_center;

}

# *************************************************************************
# FUNCTION: UploadFile
# ARGUMENTS:    
# RETURNS:  
# NOTES:    This subroutine handles data "posted" thru the form
#       created in UploadForm().
# *************************************************************************
sub UploadFile {

  my $dir = shift || die "ERROR!  No arg passed to UploadFile().\n";
  my $overwrite = shift || 0;

  my $TEMP_FH;

  # The upload() function returns the filename and a file handle.  See CGI.pm.
  $_= $TEMP_FH = upload($FILE_UPLOAD_PARAM);

  # What do all the regexes do?  I wrote them, but I forgot.  I think they
  # strip off any path information (common in IE!) to get just the filename.
  s/\w://;
  s/([^\/\\]+)$//;
  $_ = $1;
  s/\.\.+//g;
  s/\s+//g;
  my $filename = $_;
  my $serverFullFilename = "$dir/$filename";

  if (! $filename) {
    DisplayErrorPage("Illegal filename: '$filename'");
  }

  if ((! $overwrite) && (-e $serverFullFilename)) {
    die "Unable to upload file.  File '$filename' already exists.";
  }

  open(SERVER_FH,">$serverFullFilename") || die "Error opening $filename for writing.";
  binmode SERVER_FH;

  # Copy the file from the temp dir to the final location.
  while (<$TEMP_FH>) {
    print SERVER_FH;
  }

  close(SERVER_FH);
  close($TEMP_FH);

  if ((stat $serverFullFilename)[7] <= 0) {
    unlink $serverFullFilename;
    die "Unable to upload file '$filename'.  This is usually due to the user specifying an invalid or unreadable file on the user's computer.";
  }

  return $serverFullFilename;
} 

return 1;

原谅任何不一致的地方,因为我必须删除一些特定于网站的内容,但如果我正确地修剪它,那应该是“开箱即用”