文件不是使用Ajax / JQuery上传,而是使用表单提交上传

时间:2014-11-06 13:46:51

标签: jquery ajax perl file-upload image-uploading

我正在尝试使用Ajax / Jquery上传文件,实际图像文件没有上传,而是在目标目录中创建名为“object_FileList”的0字节文件。

这是我的JQuery代码。

$('#fileUpload').click(function() 
{
    alert ('reached here');
    var photo_data = $("#photo")[0].files; // Getting the properties of file from file field
    var form_data = new FormData(); // Creating object of FormData class
    form_data.append('photo', photo_data);

    $.ajax({
        url: "upload.pl",
        cache: false,
        contentType: false,
        processData: false,
        data: form_data, // Setting the data attribute of ajax with file_data
        type: 'post',
        success : function(response)
        {
            alert ("success");
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) 
        { 

          alert ("script error");


        }, // error 
    });
});

HTML代码

<input id="photo" type="file" name="photo" />
<button type='button' id='fileUpload' class='btn btn-primary btn-sm'>
   <span class='glyphicon glyphicon-upload'></span> 
   Start Upload
</button>

Perl脚本

#!c:/perl64/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 = "C:/Users/Public/";

my $cgi = new CGI;
my $filename = $cgi->param("photo");

if ( !$filename )
{
    print $cgi->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 = $cgi->upload("photo");
print $upload_filehandle;


open UPLOADFILE, ">C:/Users/Public/$filename"  or die $!;
binmode UPLOADFILE;

while ( <$upload_filehandle> )
{
print UPLOADFILE;
}

close UPLOADFILE;

print $cgi->header ();

我认为Perl脚本中没有任何问题,因为如果我使用表单数据上传文件,那么它的上传效果会很好。

<form action="upload.pl" method="post" enctype="multipart/form-data">
        <input id="photo" type="file" name="photo" />
        <input type="submit" name="Submit" value="Submit Form" />
</form>

在第一种情况下,有人可以帮助我解决问题吗? (使用Ajax / Jquery上传)??

1 个答案:

答案 0 :(得分:3)

昨天你问过一个非常类似的问题,但似乎已经改变了一些事情,并以不同的方式破坏了你的代码。这次的罪魁祸首在于您的JavaScript代码:

var photo_data = $("#photo")[0].files;

这会返回FileList object,这会使您的AJAX请求内容如下所示:

-----------------------------195229089014926488201584712872
Content-Disposition: form-data; name="photo"

[object FileList]
-----------------------------195229089014926488201584712872--

这不起作用,因为您没有发送文件的实际内容。要发送列表中第一个文件的内容,请执行以下操作:

var photo_data = $("#photo")[0].files[0];

或者,因为这里不需要jQuery,只需

var photo_data = document.getElementById("photo").files[0];

这会将请求的内容设置为更像:

-----------------------------4576019836610138732026194501
Content-Disposition: form-data; name="photo"; filename="foo.txt"
Content-Type: text/plain

foo
bar

-----------------------------4576019836610138732026194501--

请注意,如果您确实要上传像图片这样的二进制文件,则必须对代码进行其他更改。

另请注意,您的Perl脚本有一些应该修复的安全漏洞,特别是:

  1. 绝不允许用户确定系统上的文件名或路径。
  2. 使用open的3参数形式,例如open my $fh, '<', $file or die "$file: $!";
  3. 可能还有更多,但那些是一目了然的。


    关于疑难解答的说明

    无论出于何种原因,您昨天发布的代码中都有

    var file_data = $("#avatar").prop("files")[0];
    
    如果您将选择器更改为$("#photo"),那么

    也会有效。我不确定你为什么要做这个改变,因为它破坏了你正在使用的JavaScript代码。

    这就是为什么在进行故障排除时,您应该一次只进行一次更改,以帮助找出问题的原因。如果您一次进行两项更改,则可能会修复上一个问题,而另一个则会引入新错误。

    另外,我建议您自由使用浏览器的开发人员工具来解决JavaScript代码问题。这将允许您检查AJAX请求中发送的确切参数和内容,这就是我在两个问题中跟踪错误的方法。