Hochladen mehrerer Dateien mit formData ()

75
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']);

Dies funktioniert, aber offensichtlich nur für die files[0]. Wie funktioniert das für die ausgewählte Datei?

Ich habe versucht, das zu entfernen [0], aber es hat nicht funktioniert.

Jaanisk
quelle

Antworten:

93

Sie müssen die Dateilänge ermitteln, um sie in JS anzuhängen, und sie dann wie unten beschrieben per AJAX-Anfrage senden

//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/>';
}
Rowan San
quelle
6
warum filetoupload []?
Phoenix
Hat bei mir nicht funktioniert. Ich denke, es hängt davon ab, wie Ihr mehrteiliges Formular serverseitig behandelt wird.
Fubbe
gibt nur eine Datei zurück
Žilvinas
62

Der Weg zu 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);
    }
})

Wenn Sie data.append ('Datei', Datei) mehrmals aufrufen, enthält Ihre Anfrage ein Array Ihrer Dateien.

Aus MDN-Webdokumenten :

„Die append()Methode der FormDataSchnittstelle fügt einen neuen Wert auf einen vorhandenen Schlüssel in einem FormDataObjekt oder fügt den Schlüssel , wenn es nicht bereits vorhanden ist. Der Unterschied zwischen FormData.set und append()ist , dass , wenn der angegebene Schlüssel bereits vorhanden ist , FormData.setwird überschreibt alle vorhandenen Werte mit der neuer, während append()der neue Wert an das Ende des vorhandenen Wertesatzes angehängt wird. "

Wenn ich node.js und Multipart Handler Middleware Multer verwende, erhalte ich die Daten wie folgt:

router.post('/trip/save', upload.array('file', 10), function(req, res){
    // Your array of files is in req.files
}
Flaudre
quelle
16
...If you call data.append('file', file) multiple times your request will contain an array of your files...Ersparte mir Stunden der Verzweiflung, vor allem, weil ich der Meinung war, dass der Name lauten sollte file[], aber es filefunktionierte, nur zu verwenden und mehrmals anzurufen, danke!
Bourgeois247
2
Alter, du bist eine Legende, die seit dem Morgen danach gesucht hat, danke allot man
Kannan T
4
Ich habe Ihr Beispiel ausprobiert, aber wenn ich es var_dumped habe, wird immer das letzte Bild des Sets zurückgegeben. Ich habe mich geändert: data.append('file', file)zu data.append('file', i), das hat bei mir funktioniert.
Jeroen Bellemans
1
und du bist offiziell mein Held
WtFudgE
1
Diese Zeile ist die wichtigste Information. If you call data.append('file', file) multiple times your request will contain an array of your files.Vielen Dank. Hat mir Stunden meiner Zeit gespart.
LearnToLive
22

Sie müssen nur verwenden fileToUpload[]anstelle von fileToUpload:

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

Und es wird ein Array mit mehreren Namen, Größen usw. zurückgegeben.

Vincent Kelleher
quelle
4
Dies muss eine Schleife sein und jede anhängenfiles[i]
FindOutIslamNow
13

Das hat bei mir funktioniert:

let formData = new FormData()
formData.append('files', file1)
formData.append('files', file2)
Clézio Santos
quelle
1
Dateien müssen in einer Schleife angehängt werden.
Ashish Bansal
6

Dieser hat für mich gearbeitet

//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);
}

NINSIIMA WILBER
quelle
3

Das hat gut funktioniert!

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);
    }
});
Missa Constant Pierre harte Arbeit
quelle
Wenn Sie Ihrem Code eine kurze Erklärung hinzufügen, erhalten Sie eine bessere Antwort! Nur ein hilfreicher Tipp
Chevybow
1

Ich habe diese Arbeit für mich gefunden!

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;
littleSteppenWolf
quelle
1
Bitte fügen Sie Ihrer Antwort weitere Erklärungen hinzu
Parisssss
1

Stellen Sie zum Hochladen mehrerer Dateien mit eckigen Formulardaten sicher, dass diese in Ihrer component.html enthalten sind

Dokumente hochladen

                <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>

Deklarieren Sie in Ihrer Datei componenet.ts das Array wie folgt

selectedFiles = [];

// Array ausgewählter Dateien

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

// Hängen Sie in der Methode zum Hochladen von Dateien Ihre Formulardaten wie folgt an

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

HINWEIS: Ich hoffe, diese Lösung funktioniert für Sie Freunde

Banny
quelle
1

Das Hinzufügen []beim Anhängen an fd funktioniert, aber wenn Sie Ihre Daten lieber nach Dateien gruppieren möchten, würde ich Folgendes vorschlagen:

var files= document.getElementById('inpFile').files
var fd = new FormData()

for (let i = 0; i < files.length; i++) {
  fd.append(i, files[i])
}

Jetzt werden Ihre Daten gruppiert nach Dateien anstatt nach Attributen gruppiert gesendet.

Rens
quelle
Hat perfekt funktioniert!
Rohit Parte
0

Erstellen Sie ein FormDataObjekt

const formData: any = new FormData();

Und an denselben Schlüsselnamen anhängen

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

und senden Sie es an den Server

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

Dadurch wird automatisch ein Array von Objekten unter erstellt file

wenn Sie nodejs verwenden

const files :File[] = req.files ? req.files.file : null;
Sunil Garg
quelle
0

Hier ist die Vanilla JavaScript- Lösung für dieses Problem -

Zuerst verwenden wir die Array.prototype.forEach()Methode as

document.querySelectorAll('input[type=file]')Gibt ein Array-ähnliches Objekt zurück .

Dann verwenden wir die Function.prototype.call()Methode, um jedes Element im Array-ähnlichen Objekt dem thisWert in der .forEachMethode zuzuweisen .

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"));
}

Das Arbeitsbeispiel desselben können Sie HIER einsehen

Bappi Das
quelle