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

时间:2022-11-24 00:16:17

I am trying to upload a file using using Ajax/Jquery, Actual image file is not getting uploaded, instead 0 byte file named "object_FileList" getting created on the destination directory.

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

This is my JQuery Code.

这是我的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 Code

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 Script

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 ();

I don't think there is any issue in Perl script because if I'm using form data to upload the file, its uploading perfectly.

我认为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>

Can someone help me what is wrong in first case. (Uploading using Ajax/Jquery)??

有人能帮我一下第一个问题吗?(上传使用Ajax / Jquery)? ?

1 个解决方案

#1


3  

You asked a very similar question yesterday, but seem to have changed a few things and broken your code in a different way. The culprit this time is in your JavaScript code:

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

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

This returns a FileList object, which makes the content of your AJAX request look like this:

它返回一个FileList对象,使AJAX请求的内容看起来如下所示:

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

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

This is not going to work, since you're not sending the actual contents of a file. To send the contents of the first file in the list, do:

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

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

or, since jQuery isn't necessary here, simply

或者,因为jQuery在这里没有必要,简单地说

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

This sets the content of the request to something more like:

这将请求的内容设置为以下内容:

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

foo
bar

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

Note that you'll have to make additional changes to your code if you actually want to upload a binary file like an image.

注意,如果您确实想上传一个二进制文件(如图像),那么您必须对代码进行额外的修改。

Also note that your Perl script has some security holes that should be fixed, notably:

还请注意,您的Perl脚本有一些需要修复的安全漏洞,值得注意的是:

  1. Never allow users to determine filenames or paths on your system.
  2. 绝不允许用户在您的系统上确定文件名或路径。
  3. Use the 3-argument form of open, e.g. open my $fh, '<', $file or die "$file: $!";
  4. 使用开放的3-参数形式,例如:打开我的$fh、<、$file或die“$file: $!”

There are probably more, but those are the ones that jump out at a glance.

可能还有更多,但这些是那些一眼就能看出来的。


A note about troubleshooting

For whatever reason, in the code you posted yesterday you had

不管出于什么原因,在你昨天发布的代码中。

var file_data = $("#avatar").prop("files")[0];

which would also work if you changed the selector to $("#photo"). I'm not sure why you made this change, because it broke your otherwise-working JavaScript code.

如果将选择器更改为$(“#photo”),也可以使用。我不确定您为什么要做这个更改,因为它破坏了您的其他工作的JavaScript代码。

That's why in troubleshooting, you should only make one change at a time to help isolate the cause of an issue. If you make two changes at once, one might fix your previous issue while the other one introduces a new bug.

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

Also, I recommend you make liberal use of your browser's developer tools for troubleshooting your JavaScript code. This will allow you to examine the exact parameters and content being sent in your AJAX requests, which is how I tracked down the bugs in both of your questions.

此外,我建议您*地使用浏览器的开发工具来排除JavaScript代码的故障。这将允许您检查在AJAX请求中发送的确切参数和内容,这就是我在两个问题中跟踪bug的方法。

#1


3  

You asked a very similar question yesterday, but seem to have changed a few things and broken your code in a different way. The culprit this time is in your JavaScript code:

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

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

This returns a FileList object, which makes the content of your AJAX request look like this:

它返回一个FileList对象,使AJAX请求的内容看起来如下所示:

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

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

This is not going to work, since you're not sending the actual contents of a file. To send the contents of the first file in the list, do:

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

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

or, since jQuery isn't necessary here, simply

或者,因为jQuery在这里没有必要,简单地说

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

This sets the content of the request to something more like:

这将请求的内容设置为以下内容:

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

foo
bar

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

Note that you'll have to make additional changes to your code if you actually want to upload a binary file like an image.

注意,如果您确实想上传一个二进制文件(如图像),那么您必须对代码进行额外的修改。

Also note that your Perl script has some security holes that should be fixed, notably:

还请注意,您的Perl脚本有一些需要修复的安全漏洞,值得注意的是:

  1. Never allow users to determine filenames or paths on your system.
  2. 绝不允许用户在您的系统上确定文件名或路径。
  3. Use the 3-argument form of open, e.g. open my $fh, '<', $file or die "$file: $!";
  4. 使用开放的3-参数形式,例如:打开我的$fh、<、$file或die“$file: $!”

There are probably more, but those are the ones that jump out at a glance.

可能还有更多,但这些是那些一眼就能看出来的。


A note about troubleshooting

For whatever reason, in the code you posted yesterday you had

不管出于什么原因,在你昨天发布的代码中。

var file_data = $("#avatar").prop("files")[0];

which would also work if you changed the selector to $("#photo"). I'm not sure why you made this change, because it broke your otherwise-working JavaScript code.

如果将选择器更改为$(“#photo”),也可以使用。我不确定您为什么要做这个更改,因为它破坏了您的其他工作的JavaScript代码。

That's why in troubleshooting, you should only make one change at a time to help isolate the cause of an issue. If you make two changes at once, one might fix your previous issue while the other one introduces a new bug.

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

Also, I recommend you make liberal use of your browser's developer tools for troubleshooting your JavaScript code. This will allow you to examine the exact parameters and content being sent in your AJAX requests, which is how I tracked down the bugs in both of your questions.

此外,我建议您*地使用浏览器的开发工具来排除JavaScript代码的故障。这将允许您检查在AJAX请求中发送的确切参数和内容,这就是我在两个问题中跟踪bug的方法。