【问题标题】:Uploading multiple files using formData()使用 formData() 上传多个文件
【发布时间】:2012-10-10 23:09:22
【问题描述】:
var fd = new FormData();
fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
var xhr = new XMLHttpRequest();
xhr.open("POST", "uph.php");
xhr.send(fd);

uph.php:

var_dump($_FILES['fileToUpload']);

这有效,但显然仅适用于files[0]。如何使它适用于所选文件?

我尝试删除[0],但没有成功。

【问题讨论】:

    标签: javascript arrays upload xmlhttprequest


    【解决方案1】:

    您只需要使用fileToUpload[] 而不是fileToUpload

    fd.append("fileToUpload[]", document.getElementById('fileToUpload').files[0]);
    

    它会返回一个包含多个名称、大小等的数组...

    【讨论】:

    • 这需要循环,并附加每个files[i]
    【解决方案2】:

    您必须获取文件长度以附加到 JS 中,然后通过 AJAX 请求发送,如下所示

    //JavaScript 
    var ins = document.getElementById('fileToUpload').files.length;
    for (var x = 0; x < ins; x++) {
        fd.append("fileToUpload[]", document.getElementById('fileToUpload').files[x]);
    }
    
    //PHP
    $count = count($_FILES['fileToUpload']['name']);
    for ($i = 0; $i < $count; $i++) {
        echo 'Name: '.$_FILES['fileToUpload']['name'][$i].'<br/>';
    }
    

    【讨论】:

    【解决方案3】:

    使用 javascript 的方法:

    var data = new FormData();
    
    $.each($("input[type='file']")[0].files, function(i, file) {
        data.append('file', file);
    });
    
    $.ajax({
        type: 'POST',
        url: '/your/url',
        cache: false,
        contentType: false,
        processData: false,
        data : data,
        success: function(result){
            console.log(result);
        },
        error: function(err){
            console.log(err);
        }
    })
    

    如果您多次调用 data.append('file', file),您的请求将包含您的文件数组。

    From MDN web docs:

    FormData 接口的append() 方法将一个新值附加到FormData 对象内的现有键上,如果该键不存在,则添加该键。 FormData.set 和 append() 之间的区别在于,如果指定的键已经存在,FormData.set 将用新的值覆盖所有现有值,而 append() 会将新值附加到现有值集的结尾。”

    我自己使用node.js和multipart handler中间件multer获取数据如下:

    router.post('/trip/save', upload.array('file', 10), function(req, res){
        // Your array of files is in req.files
    }
    

    【讨论】:

    • ...If you call data.append('file', file) multiple times your request will contain an array of your files... 救了我几个小时的绝望,特别是因为我觉得名字应该是file[],但只使用file 并多次调用有效,谢谢!
    • 老兄,你是个传奇,从早上开始就一直在寻找这个,谢谢分配人
    • 我试过你的例子,但是当我 var_dumped 它时,它总是返回集合的最后一个图像。我将:data.append('file', file) 更改为 data.append('file', i),这对我有用。
    • 你是我的英雄
    • 这一行是最重要的信息If you call data.append('file', file) multiple times your request will contain an array of your files. 非常感谢。节省了我数小时的时间。
    【解决方案4】:

    这很好用!

    var fd = new FormData();
    
    $('input[type="file"]').on('change', function (e) {
        [].forEach.call(this.files, function (file) {
            fd.append('filename[]', file);
        });
    });
    
    $.ajax({
        url: '/url/to/post/on',
        method: 'post',
        data: fd,
        contentType: false,
        processData: false,
        success: function (response) {
            console.log(response)
        },
        error: function (err) {
            console.log(err);
        }
    });
    

    【讨论】:

    • 在你的代码中添加一个简短的解释将会得到一个更好的答案!只是一个有用的提示
    【解决方案5】:

    这对我有用:

    let formData = new FormData()
    formData.append('files', file1)
    formData.append('files', file2)
    

    【讨论】:

    • 文件必须在循环中追加。
    【解决方案6】:

    这个对我有用

    //Javascript part
    //file_input is a file input id
    var formData = new FormData();
    var filesLength=document.getElementById('file_input').files.length;
    for(var i=0;i<filesLength;i++){
    	formData.append("file[]", document.getElementById('file_input').files[i]);
    }
    $.ajax({
       url: 'upload.php',
       type: 'POST',
       data: formData,
       contentType: false,
       cache: false,
       processData: false,
       success: function (html) {
       
      }
    });

    <?php
    //PHP part
    $file_names = $_FILES["file"]["name"];
    for ($i = 0; $i < count($file_names); $i++) {
       $file_name=$file_names[$i];
       $extension = end(explode(".", $file_name));
       $original_file_name = pathinfo($file_name, PATHINFO_FILENAME);
       $file_url = $original_file_name . "-" . date("YmdHis") . "." . $extension;
     move_uploaded_file($_FILES["file"]["tmp_name"][$i], $absolute_destination . $file_url);
    }

    【讨论】:

      【解决方案7】:

      这是针对此问题的 Vanilla JavaScript 解决方案 -

      首先,我们将使用Array.prototype.forEach() 方法,如

      document.querySelectorAll('input[type=file]') 返回一个类似对象的数组

      然后我们将使用Function.prototype.call() 方法将类数组对象 中的每个元素分配给.forEach 方法中的this 值。

      HTML

      <form id="myForm">
      
          <input type="file" name="myFile" id="myFile_1">
          <input type="file" name="myFile" id="myFile_2">
          <input type="file" name="myFile" id="myFile_3">
      
          <button type="button" onclick="saveData()">Save</button>
      
      </form>
      

      JavaScript

       function saveData(){
           var data = new FormData(document.getElementById("myForm"));
           var inputs = document.querySelectorAll('input[type=file]');
      
           Array.prototype.forEach.call(inputs[0].files, function(index){
              data.append('files', index);
           });
           console.log(data.getAll("myFile"));
      }
      

      您可以查看同一HERE的工作示例

      【讨论】:

        【解决方案8】:

        创建一个FormData 对象

        const formData: any = new FormData();
        

        并附加到相同的 keyName

        photos.forEach((_photoInfo: { localUri: string, file: File }) => {
            formData.append("file", _photoInfo.file);
        });
        

        并将其发送到服务器

        // angular code
        this.http.post(url, formData)
        

        这将自动在file下创建一个对象数组

        如果你使用的是 nodejs

        const files :File[] = req.files ? req.files.file : null;
        

        【讨论】:

          【解决方案9】:

          我为我找到了这份工作!

          var fd = new FormData();
          $.each($('.modal-banner [type=file]'), function(index, file) {
            fd.append('item[]', $('input[type=file]')[index].files[0]);
          });
          
          $.ajax({
            type: 'POST',
            url: 'your/path/', 
            data: fd,
            dataType: 'json',
            contentType: false,
            processData: false,
            cache: false,
            success: function (response) {
              console.log(response);
            },
            error: function(err){
              console.log(err);
            }
          }).done(function() {
            // do something....
          });
          return false;
          

          【讨论】:

          • 请为您的答案添加更多解释
          【解决方案10】:

          要上传多个带有角度表单数据的文件,请确保您的 component.html 中有此文件

          上传文件

                          <div class="row">
          
          
                            <div class="col-md-4">
                               &nbsp; <small class="text-center">  Driver  Photo</small>
                              <div class="form-group">
                                <input  (change)="onFileSelected($event, 'profilepic')"  type="file" class="form-control" >
                              </div>
                            </div>
          
                            <div class="col-md-4">
                               &nbsp; <small> Driver ID</small>
                              <div class="form-group">
                                <input  (change)="onFileSelected($event, 'id')"  type="file" class="form-control" >
                              </div>
                            </div>
          
                            <div class="col-md-4">
                              &nbsp; <small>Driving Permit</small>
                              <div class="form-group">
                                <input type="file"  (change)="onFileSelected($event, 'drivingpermit')" class="form-control"  />
                              </div>
                            </div>
                          </div>
          
          
          
                          <div class="row">
                              <div class="col-md-6">
                                 &nbsp; <small>Car Registration</small>
                                <div class="form-group">
                                  <div class="input-group mb-4">
                                      <input class="form-control" 
                          (change)="onFileSelected($event, 'carregistration')" type="file"> <br>
                                  </div>
                                </div>
                              </div>
          
                              <div class="col-md-6">
                                  <small id="li"> Car Insurance</small>
                                <div class="form-group">
                                  <div class="input-group mb-4">
                                    <input class="form-control" (change)="onFileSelected($event, 
          
                                   'insurancedocs')"   type="file">
                                  </div>
                                </div>
                              </div>
          
                            </div>
          
          
                          <div style="align-items:c" class="modal-footer">
                              <button type="button" class="btn btn-secondary" data- 
                            dismiss="modal">Close</button>
                              <button class="btn btn-primary"  (click)="uploadFiles()">Upload 
                            Files</button>
                            </div>
                        </form>
          

          在您的 componenet.ts 文件中 像这样声明数组选择的文件

          selectedFiles = [];
          

          // 所选文件的数组

          onFileSelected(event, type) {
              this.selectedFiles.push({ type, file: event.target.files[0] });
            }
          

          //在上传文件方法中,像这样附加你的表单数据

          uploadFiles() {
              const formData = new FormData(); 
          
              this.selectedFiles.forEach(file => {
                formData.append(file.type, file.file, file.file.name); 
              });
              formData.append("driverid", this.driverid);
          
              this.driverService.uploadDriverDetails(formData).subscribe(
                res => {
                  console.log(res); 
          
                },
                error => console.log(error.message)
              );
            }
          

          注意:我希望这个解决方案对你的朋友有用

          【讨论】:

            【解决方案11】:

            在附加到 fd 时添加 [] 有效,但如果您希望将数据按文件分组,那么我建议您这样做:

            var files= document.getElementById('inpFile').files
            var fd = new FormData()
            
            for (let i = 0; i < files.length; i++) {
              fd.append(i, files[i])
            }
            

            现在您的数据将按文件分组发送,而不是按属性分组。

            【讨论】:

              【解决方案12】:

              我的工作是这样的:

              var images = document.getElementById('fileupload').files;
              var formData = new FormData();
              for(i=0; i<images.length; i++) {
                   formData.append('files', images[i]);
              }
              

              【讨论】:

                【解决方案13】:

                这对我有用

                var ins = $('.file').map(function () {
                    return this.files;
                }).get();
                
                for (var x = 0; x < ins; x++) {
                    formData.append("file", ins[x][0]);
                }
                

                【讨论】:

                  【解决方案14】:

                  如果您正在实例化 FormData 对象,该对象已经将表单作为构造函数参数传递,则输入文件的名称属性必须包含方括号。

                  HTML:

                  <form id="myForm" method="POST" action="url" enctype="multipart/form-data">
                  <input class="form-control form-control-lg" type="file" name="photos[]" multiple />
                  

                  JS:

                  var formData = new FormData(document.getElementById('myForm'));
                  console.log(formData.getAll('photos[]'));
                  

                  这对我有用!

                  【讨论】:

                    【解决方案15】:

                    如果我们在 html 中有输入:

                    <input id="my-input" type="file" mutliple /> // multiple attribute to select and upload multiple files
                    

                    我们可以从该输入中获取文件并使用纯 js 脚本将其发送到服务器:

                    const myInput = document.getElementById('my-input') // getting our input
                    
                    myInput.addEventListener('change', (event) => { // listening for file uploads
                        const files = event.target.files // getting our files after upload
                        const formData = new FormData() // create formData
                    
                        for (const file of files) {
                            formData.append('files', file) // appending every file to formdata
                        }
                    
                        const URL = 'http://server.com:3000'
                        const response = fetch(URL, {
                           method: 'POST',
                           data: formData // sending our formdata in body of post request
                        })
                    
                        return response.json() 
                    }
                    

                    它非常适合我

                    P.S.:我在后端(node.js + express)使用multer,添加到文件上传路径

                    upload.array("files", 10)
                    
                    • 第一个参数是我们文件的属性名称(在 formdata 中)
                    • 第二个参数是最大文件大小

                    【讨论】:

                    • 域不使用端口(@98​​7654325@),仅适用于本地服务器。
                    • 是的,当然,如果您在前端上传图片,您会获取图片并将其发送到带有 host:port 的后端服务器
                    • 是的,本地服务器不是域。
                    猜你喜欢
                    • 2017-06-04
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-04-06
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多