Uploading multiple files using formData()
JavascriptArraysUploadXmlhttprequestJavascript Problem Overview
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']);
This works, but obviously for the files[0]
only. How to get this working for chosen file?
I tried removing the [0]
, but it didn't work.
Javascript Solutions
Solution 1 - Javascript
You have to get the files length to append in JS and then send it via AJAX request as below
//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/>';
}
Solution 2 - Javascript
The way to go with 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);
}
})
If you call data.append('file', file) multiple times your request will contain an array of your files.
>"The append()
method of the FormData
interface appends a new value onto an existing key inside a FormData
object, or adds the key if it does not already exist.
>The difference between FormData.se
t and append()
is that if the specified key already exists, FormData.set
will overwrite all existing values with the new one, whereas append()
will append the new value onto the end of the existing set of values."
Myself using node.js and multipart handler middleware multer get the data as follows:
router.post('/trip/save', upload.array('file', 10), function(req, res){
// Your array of files is in req.files
}
Solution 3 - Javascript
You just have to use fileToUpload[]
instead of fileToUpload
:
fd.append("fileToUpload[]", document.getElementById('fileToUpload').files[0]);
And it will return an array with multiple names, sizes, etc...
Solution 4 - Javascript
This worked for me:
let formData = new FormData()
formData.append('files', file1)
formData.append('files', file2)
Solution 5 - Javascript
This one worked for me
//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);
}
Solution 6 - Javascript
Adding []
when appending to fd works, but if you prefer to have your data grouped by file then I'd suggest doing it this way:
var files= document.getElementById('inpFile').files
var fd = new FormData()
for (let i = 0; i < files.length; i++) {
fd.append(i, files[i])
}
Now your data will be sent grouped by file instead of grouped by attribute.
Solution 7 - Javascript
This worked fine !
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);
}
});
Solution 8 - Javascript
I worked that such as:
var images = document.getElementById('fileupload').files;
var formData = new FormData();
for(i=0; i<images.length; i++) {
formData.append('files', images[i]);
}
Solution 9 - Javascript
This worked for me
var ins = $('.file').map(function () {
return this.files;
}).get();
for (var x = 0; x < ins; x++) {
formData.append("file", ins[x][0]);
}
Solution 10 - Javascript
If we have input in our html:
<input id="my-input" type="file" mutliple /> // multiple attribute to select and upload multiple files
We can get files from that input and send it to server with pure js script:
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()
}
It worked perfect for me
P.S.: I used multer
in backend (node.js + express), added to file upload route
upload.array("files", 10)
- First argument is a property name of our files (in formdata)
- Second argument is max file size
Solution 11 - Javascript
I found this work for me!
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;
Solution 12 - Javascript
To upload multiple files with angular form data, make sure you have this in your component.html
Solution 13 - Javascript
If you are instantiating the FormData object already passing the form as a constructor parameter, the input file's name attribute must contain the square brackets.
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[]'));
That worked for me!
Solution 14 - Javascript
Here is the Vanilla JavaScript solution for this issue -
First, we'll use Array.prototype.forEach()
method, as
document.querySelectorAll('input[type=file]')
returns an array like object.
Then we'll use the Function.prototype.call()
method to assign each element in the array-like object to the this
value in the .forEach
method.
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"));
}
You can view the working example of the same HERE
Solution 15 - Javascript
Create a FormData
object
const formData: any = new FormData();
And append to the same keyName
photos.forEach((_photoInfo: { localUri: string, file: File }) => {
formData.append("file", _photoInfo.file);
});
and send it to server
// angular code
this.http.post(url, formData)
this will automatically create an array of object under file
if you are using nodejs
const files :File[] = req.files ? req.files.file : null;