【问题标题】:AJAX Multiple File Upload - Identifying original element?AJAX 多文件上传 - 识别原始元素?
【发布时间】:2021-03-05 08:36:12
【问题描述】:

假设HTML页面上存在多种上传输入类型,我希望能够获取每个文件上传的name属性,这样PHP服务器端可以准确地确定文件上传者正在传递什么文件。

我的代码:

$('.php-email-form').submit(function (event) {
  event.preventDefault();
  
  var form = $(this);
  var data = new FormData();
  
  // add datas of input not file to data object
  $.each($(':input', form).not(':input[type=submit]'), function(i, fields){
    data.append($(fields).attr('name'), $(fields).val());
    console.log($(fields).attr('name'), $(fields).val());
  });    
  
  // add data from inputs type file
  $.each($('input[type=file]', form)[0].files, function (i, file) {
    data.append(file.name, file);
    console.log(file.name);
    console.log($(this).attr('name')); // test, trying to get the name attribute of input type file
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="php-email-form" enctype="multipart/form-data">
  <input type="text" name="test" value="value"><br>
  <input type="file" class="custom-file-input" id="photo" name="photo"><br>
  <input type="submit">
</form>

当我查看 PHP 中的 $_FILES 数组时,我得到以下输出:

array(1) { ["test"]=> string(5) "value" }

array(1) { ["IMG_8085_JPG"]=> array(5) { ["name"]=> string(12) "IMG_8085.JPG" ["type"]=> string(10) "image/jpeg" ["tmp_name"]=> string(14) "/tmp/phpxsP6RN" ["error"]=> int(0) ["size"]=> int(65949) } }

如上所示,上面图像的索引是图像名称​​(IMG_8085_JPG),尽管我希望这个索引是它来自的原始输入的名称。 (照片或照片 2)

因此,如果在 photo 元素中上传了一张图片,则该数组应如下所示:

array(1) { ["test"]=> string(5) "value" }

array(1) { ["photo"]=> array(5) { ["name"]=> string(12) "IMG_8085.JPG" ["type"]=> string(10) "image/jpeg" ["tmp_name"]=> string(14) "/tmp/phpxsP6RN" ["error"]=> int(0) ["size"]=> int(65949) } }

似乎name 索引在上传文件时被覆盖在元素上,因此$(this).attr("name") 不再引用该属性,而是成为上传文件的名称。

我在下面发布了我所有的 jQuery 代码:

$('.php-email-form').submit(function (event) {
    event.preventDefault();

    var form = $(this);     
    var formAction = $(form).attr('action');
    var data = new FormData();

    // add data from inputs type text
    $.each($(':input', form).not(':input[type=submit]'), function(i, fields){
      data.append($(fields).attr('name'), $(fields).val());
    });    

    // add data from inputs type file
    $.each($('input[type=file]', form)[0].files, function (i, file) {
      data.append(file.name, file);
      console.log(file);
      console.log($(this).attr('name'));
    });

    $('.loading').fadeIn();

    $.ajax({
      url: formAction,
      type: "POST",
      data: data,
      contentType: false,
      cache: false,
      processData: false,
    }).done(function(data){
      $('.loading').hide();
      $('.sent-message').fadeIn().html(data);
    }).fail(function(jqXHR, textStatus, errorThrown) {
      $('.loading').hide();
      $('.error-message').show().html(errorThrown);
    });
  });
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;

当我 var_dump $_POST & $_FILES 时我期望的结果:

array(1) { ["test"]=> string(5) "value" }


array(1) { ["photo"]=> array(5) { ["name"]=> string(12) "IMG_8085.JPG" ["type"]=> string(10) "image/jpeg" ["tmp_name"]=> string(14) "/tmp/phpxsP6RN" ["error"]=> int(0) ["size"]=> int(65949) } } 

【问题讨论】:

  • 输入的名称是什么意思?你的意思是你只想要上传是什么类型,在这种情况下是“image/jpeg”?
  • 我想要这个数组,但用输入名称属性命名
  • 你能举例说明你希望数组的外观吗?我不明白你想要输入名称属性是什么意思。您的意思是您只想将数组索引命名为“照片”吗?
  • 我看到了 sn-p,但这仅显示了给出文件名的 jQuery 的结果。当您在服务器上获取文件时,您希望在 PHP 中拥有“照片”索引,对吗?
  • 是的,但我从数组 $_FILES 中的 php 文件中得到了这个答案

标签: php jquery ajax


【解决方案1】:

您直接遍历每个输入的文件而不是元素本身,这使得 type 属性可访问。

$.each($('input[type=file]', form), function(i, file) { // Iterate through every file upload element.
    let uploadedFile = this.files[0]; // Get the file that was uploaded to this input.
    data.append(this.name, uploadedFile); // Append it to the form data under the index of the name of the input it was provided in.

    // Testing.
    console.log(this.name); // input name (in this case, 'photo')
    console.log(uploadedFile); // uploaded file element object.
});

这里的区别在于,当您遍历 ('input[type=file]', form)[0].files 时,您是在直接访问文件,并且由于没有对它们的引用,因此无法访问它们来自的父输入。

解决方案是使用“文件”类型遍历每个输入,这样我们仍然可以获取每个输入并可以访问“名称”属性,然后我们可以使用@987654323 获取在循环中上传的文件本身@。 (获取上传的第一个文件。)

【讨论】:

  • 感谢您的帮助,但您的代码出现内部服务器错误
  • 您是否仍然遇到此错误?我再次测试了代码,它运行得很好,你确定这不是你的内部错误吗?
  • 我在我的 php 文件中修复了这个问题。谢谢你的一切
【解决方案2】:

代码中缺少的主要内容是表单的enctype 属性。每当您在表单中使用文件输入时,都必须将 enctype 指定为 multipart/form-data

将您的表单标签更改为:

<form class="php-email-form" enctype="multipart/form-data">

现在您可以像这样简单地发送表单(无需手动分配值)

$('.php-email-form').submit(function(event) {
    event.preventDefault();
    var myFormData = new FormData($(this)[0]);
    $.ajax({
        type: 'POST',
        url: 'test-dest.php',
        data: myFormData,
        contentType: false,
        processData: false,
        cache: false,
        success: function(data) {
            console.log(data);
        }
    });
});

并使用来自 test-dest.php 的 $_FILES 回显

echo var_dump($_FILES);

这会给你结果

    array(1) {
  ["photo"]=>
  array(5) {
    ["name"]=>
    string(14) "web-design.png"
    ["type"]=>
    string(9) "image/png"
    ["tmp_name"]=>
    string(25) "D:\myfolder\tmp\phpC00E.tmp"
    ["error"]=>
    int(0)
    ["size"]=>
    int(4001)
  }
}

【讨论】:

  • 感谢您的回复,但当我尝试您的代码时出现错误
  • 你能在这里分享错误吗?我已经执行了代码,没有任何错误。 @The_Death_Raw
  • [HTTP/1.1 500 内部服务器错误 90ms]
  • 你能显示你的 test-dest.php 代码吗?内部服务器很可能出现在那里。
  • 我在我的 php 文件中修复了这个问题。 Skully 和你的答案有效,但我验证 Skully 的答案,因为他是第一个回答的人。谢谢你的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
相关资源
最近更新 更多