2010-08-10 56 views
4

Firefox 3.6引入了[常规类型=“文件”输入元素的多重属性]( http://hacks.mozilla.org/2009/12/multiple-file-input-in-firefox-3-6/)。Perl的CGI.pm能处理Firefox的<input type =“file”,multiple =“”>表单字段吗?

我无法让Perl来处理这些字段。我可以在这样的列表环境中调用该字段:

my @files = $CGIobject->param("File_Input"); 

通过循环,将给我的文件名称作为字符串,但没有别的。

任何建议将非常欢迎。

这里的HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html> 

    <head> 
    <title>Multiple file upload test</title> 

    </head> 

    <body> 

    <form action="deliberately_obfuscated" 
      method="post" 
     enctype="multipart/form-data"> 

     <input type="file" 
      name="multiple_files" 
     multiple="true"/> 

     <button type="submit">Submit</button> 

    </form> 

    </body> 

</html> 

这里是Perl:

#!/usr/bin/perl 

#use strict; 
#use warnings; 

use CGI; 

my $CGIo = new CGI; 

print $CGIo->header(); 

@lightweight_fh = $CGIo->upload('myfiles'); 

# undef may be returned 
# if it's not a 
# valid file handle 

if (@lightweight_fh) { 

    # Upgrade the handle to 
    # one compatible with IO::Handle: 

    my $io_handle = $lightweight_fh->handle; 

    open (OUTFILE,'>>','/hidden_deliberately/'); 

    while ($bytesread = $io_handle->read($buffer,1024)){ 

    print OUTFILE $buffer; 

    } 

} 

脚本不会进入

if (@lightweight_fh) { 

块。

我试过数据:在iflight块之前的@lightweight_fh上的Dumper,它从字面上完全没有打印任何东西。

+0

多文件输入将为您提供一个字段数组,其中只有一个字段。我不会说Perl,所以我不知道如何改变语法,但它应该非常简单。 – 2010-08-10 10:51:20

+0

始终发布完整的示例脚本,以便我们可以看到您所做的一切。 – 2010-08-10 12:16:00

回答

5

呜呼,得到了这个工作。大手刹问题?旧的CGI.pm版本!很遗憾,CGI.pm文档不包含诸如“版本X中引入的”等功能的注释。许多其他模块/库/软件包。

碰巧我的版本是3.15,当前是3.49。我甚至在严格模式下工作。有人知道斯坦因为什么使用非严格的例子吗?

这里的XHTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html> 

    <head> 
    <title>Multiple file upload test</title> 

    </head> 

    <body> 

    <form action="deliberately_hidden" 
      method="post" 
     enctype="multipart/form-data"> 

     <input type="file" 
      name="multiple_files" 
     multiple="true"/> 

     <button type="submit">Submit</button> 

    </form> 

    </body> 

</html> 

这里的Perl的:

#!/usr/bin/perl 

    use strict; 
    use warnings; 

    use CGI; 

    my $CGIo = new CGI; 

    print $CGIo->header(); 

    my @lightweight_fh = $CGIo->upload('multiple_files'); 

    foreach my $fh (@lightweight_fh) { 

    # undef may be returned if it's not a valid file handle 

    if (defined $fh) { 

     # Upgrade the handle to one compatible with IO::Handle: 

     my $io_handle = $fh->handle; 

     open (OUTFILE,'>>','/deliberately_hidden/' . $fh); 

     while (my $bytesread = $io_handle->read(my $buffer,1024)) { 

     print OUTFILE $buffer 

     } 

    } 

    } 

感谢您的帮助大家。

6

CGI.pm中使用upload方法。

在列表上下文中,upload()将返回一个文件句柄数组。这使得可以处理多个上传字段使用相同名称的表单。

+1

严格来说,表单并未发送“多个上传字段”。表单正在发送具有多个值的单独上传字段。 因此,CGI.pm文档的摘录是否适用? – 2010-08-11 06:56:19

3

它看起来并不像你在使用CGI.pm跟踪Processing a file upload field的文档。在我们深入研究这个问题之前,你可以使用文档化的方法来完成一个文件吗?

+0

我最初并未遵循记录的方法,但正如您所看到的,我已经尝试了上述编辑过的示例,但该方法似乎也不奏效。 对不起,这个例子没有很好的格式,但我是新来张贴在这个网站上。 – 2010-08-11 06:50:26

1

是,Perl的CGI.pm可以proess Firefox的多文件上传

想看?使用此快捷方式:

use Data::Dumper; 
print '<pre>', $CGIo->escapeHTML(Dumper($CGIo)),'</pre>'; 

你会看到类似这样的:

$VAR1 = bless({ 
     '.parameters' => [ 
          'filename', 
          'submit' 
          ], 
     'use_tempfile' => 1, 
     '.tmpfiles' => { 
          '*Fh::fh00003temp-2.txt' => { 
                 'info' => { 
                    'Content-Type' => 'text/plain', 
                    'Content-Disposition' => 'form-data; name="filename"; filename="temp-2.txt"' 
                    }, 
                 'name' => bless(do{\(my $o = 'C:\\WINDOWS\\TEMP\\CGItemp52869')}, 'CGITempFile'), 
                 'hndl' => bless(\*{'Fh::fh00003temp-2.txt'}, 'Fh') 
                 }, 
          '*Fh::fh00001temp-1.txt' => { 
                 'info' => { 
                    'Content-Type' => 'text/plain', 
                    'Content-Disposition' => 'form-data; name="filename"; filename="temp-1.txt"' 
                    }, 
                 'name' => bless(do{\(my $o = 'C:\\WINDOWS\\TEMP\\CGItemp52775')}, 'CGITempFile'), 
                 'hndl' => bless(\*{'Fh::fh00001temp-1.txt'}, 'Fh') 
                 } 
         }, 
     '.charset' => 'ISO-8859-1', 
     'param' => { 
         'filename' => [ 
             $VAR1->{'.tmpfiles'}{'*Fh::fh00001temp-1.txt'}{'hndl'}, 
             $VAR1->{'.tmpfiles'}{'*Fh::fh00003temp-2.txt'}{'hndl'} 
            ], 
         'submit' => [ 
            'Process File' 
            ] 
        }, 
     'escape' => 1, 
     '.header_printed' => 1 
     }, 'CGI'); 

首先你打电话给你的文件上传现场File_Input,那么你怎么称呼它multiple_files,那么你怎么称呼它MYFILES - 你必须使用相同的名字,这很重要。

此外,$ lightweight_fh和@lightweight_fh是两个不同的变量,你需要

for my $lightweight_fh ($CGIo->upload('multiple_files')){ 
    my $io_handle = $lightweight_fh->handle; 
    ... 
} 

此外,您尝试打开一个目录“/ hidden_​​deliberately /”作为一个文件,你不检查对于错误

+0

Hi Tago。我保证字段的命名不适用于我的测试。我的答案始终使用“multiple_files”。不同的命名只是一个错误。 与/ hidden_​​directory /相同。只是试图混淆隐私原因的道路。我确实有“或者死亡$!”在公开招募的结尾,但由于堆栈溢出的愚蠢的窄列布局而被切断。 Re @lightwight_fh vs $ lightweight_fh我知道他们是不同的变数,但是我对上下文感到困惑,并且一度在努力获得使用doc'd方法上传的多字段的第一个文件。 – 2010-08-14 07:44:57

相关问题