I have a simple form so you can upload images. I store the uploaded images' properties in a array but I want to post this array to a PHP file using ajax. If I try to get the uploaded image: $_FILES['image1'], it returns an empty array. Any idea what I am doing wrong?
PS: It is important to store the images' properties in a array and pass it to a FormData.
var foo = []; var input = document.getElementById('input');
document.getElementById('add').addEventListener('click', () => {
foo.push(input.files[0]);
});
document.getElementById('check').addEventListener('click', () => {
console.log(foo);
});
document.getElementById('upload').addEventListener('click', () => {
var fd = new FormData();
for (let i = 0; i < foo.length; i++) {
fd.append('image'+i, foo[i]);
}
$.ajax({
enctype: "multipart/form-data",
type: "POST",
url: "path/to/php.file",
data: fd,
dataType: 'json',
contentType: false,
processData: false,
success: function(data) { console.log(data); },
error: function (err) { console.log(err); }
});
});
<button id="add">ADD</button>
<button id="check">CHECK</button>
<button id="upload">UPLOAD</button>
<br><br>
<input type="file" id="input" placeholder="UPLOAD IMAGE">
And the PHP file:
<?php
$arr = array();
array_push($arr, $_FILES);
die(json_encode($arr));
?>
Or you need to check php.ini and check if the size of all the images you add exceeds "upload_max_filesize"
I executed the code with two files. It seems that you can print the files successfully with the following code (PHP file)
print_r($_FILES['image0']);
print_r($_FILES['image1']);
I used jquery 3.5.1, for the ajax call.
I hope it helps.
I have some text input and images on my server-side. and
I need to send this data as a JSON object. But I can not send images like this because of FormData.So I need to convert my form data to one single JSON object.
Please Help me...
Thank You..!
HTML part -
<form>
<div class="form-group">
<label for="txtcustomerImage"> <i class="tags icon"></i> Image Of Your NIC</label>
<input class="form-control-file" id="txtcustomerImage" type="file" name="txtcustomerImage">
</div>
</form>
Ajax Part -
$('#btnCreateNewAccount').click(function () {
var fileObject = $("#txtcustomerImage")[0].files[0];//access file object from input field
var fileName = $("#txtcustomerImage")[0].files[0].name; //get file name
var form = new FormData(); //setup form data object to send file data
form.append("custImage", fileObject, fileName); //append data
console.log('clicked..');
let customerNIC = $('txtcustomerNIC').val();
let customerName = $('txtcustomerName').val();
let customerAddress = $('txtcustomerAddress').val();
console.log(form)
$.ajax({
method: "post",
url: "http://localhost:8080/Sprinf_Final-Back-end/customer",
contentType: "application/json",
data: JSON.stringify({
customerNIC: customerNIC,
customerName: customerName,
customerAddress: customerAddress,
}),
success: function (res) {
if (res.massage == 'Success') {
alert('Your Account is Successfully Created!When You Log to Server Use Your User Name & Password..!');
console.log(res);
} else {
console.log('error');
}
}
});
});
It doesn't make sense to create a FormData object if you want to send the data as JSON. You can read the file content with fileObject.text() and send it:
$('#btnCreateNewAccount').click(async function() {
const fileObject = $("#txtcustomerImage")[0].files[0]; //access file object from input field
const fileName = fileObject.name; //get file name
const data = JSON.stringify({
fileObject: await fileObject.text(),
fileName
})
console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="form-group">
<label for="txtcustomerImage"> <i class="tags icon"></i> Image Of Your NIC</label>
<input class="form-control-file" id="txtcustomerImage" type="file" name="txtcustomerImage">
</div>
</form>
<button id="btnCreateNewAccount">
Click
</button>
In my application, I have one form which is rendering from partial view. From that form I want to send whole form data and selected file of file control. Form submission is using ajax call. To save selected file to folder, code I have is like below :
JavaScript function :
<script type="text/javascript">
$(function () {
$('#careerForm').submit(function (e) {
e.stopPropagation();
e.preventDefault();
var formData = new FormData();
var totalFiles = document.getElementById("fuUploadCV").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("fuUploadCV").files[i];
formData.append("FileUpload", file);
}
$.ajax({
type: "POST",
url: '/CareerSurface/UploadImage/', //put your controller/action here
data: formData,
dataType: 'json',
contentType: false,
processData: false,
beforeSend: function (xhr) {
//do something before send
},
success: function (data) {
//do something if success
},
error: function (data) {
//do something if error
}
});
});
});
</script>
Html :
using (Html.BeginForm("ApplyNow", "CareerSurface", FormMethod.Post, new { enctype = "multipart/form-data", autocomplete = "off", id ="careerForm" })){
<div class="Field-Label-Box">
<label>First Name:<span> *</span></label>
</div>
<div class="Field-Value-Box">
#Html.TextBoxFor(model => model.FirstName, new { id = "txtFirstName", name = "txtFirstName", required = "required" })
#Html.ValidationMessageFor(model => model.FirstName)
</div>
......
<div class="Field-Label-Box">
<label>Upload CV:<span> *</span></label>
</div>
<div class="Field-Value-Box">
#Html.TextBoxFor(model => model.ResumeUpload, new { type = "file", id = "fuUploadCV", name = "fuUploadCV", required = "required" })</div>
<input type="submit" id="btnSave" value="Submit" name="btnSave" />
}
c# :
[HttpPost]
public void UploadImage()
{
if (Request.Files.Count > 0)
{
dynamic file = Request.Files[0];
//do something with your 'file'
}
}
This works perfect to send only selected file. Now my issue is I want to send all another data(model class object) also to the same controller method. I have tried using json also but getting error of 'Illegal Invocation'.
Please guide me how to pass both to gather to single method? If any query, fill free to ask. Help me I got stuck at this point.
Thanks.
I made a test on your code and the only thing you are missing is adding the other fields to the FormData object you are sending through AJAX. What I mean is to modify your javascript code like this:
var formData = new FormData();
var totalFiles = document.getElementById("fuUploadCV").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("fuUploadCV").files[i];
formData.append("FileUpload", file);
}
// This is what you are missing: adding the other form fields
var txtFirstName = $("#txtFirstName").val();
formData.append("txtFirstName", txtFirstName);
$.ajax({
(... the rest of your code ...)
You need to append every value of your form you want to send to the server.
Then in the server side, you can access your fields in the following way, also based on your current code:
[HttpPost]
public void UploadImage()
{
if (Request.Files.Count > 0)
{
dynamic file = Request.Files[0];
//do something with your 'file'
// This is the way to access your fields based on your code
string txtFirstName = Request.Form["txtFirstName"];
// do something with your fields
}
}
I hope that helps.
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.
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/>';
}
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.
From MDN web docs:
"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.set 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
}
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...
This worked for me:
let formData = new FormData()
formData.append('files', file1)
formData.append('files', file2)
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);
}
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.
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]);
}
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);
}
});
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]);
}
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!
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://api.server.com'
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
This worked for me also:
var data = new FormData();
for (const key in files)
data.append('gallery[]',files[key])
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
To upload multiple files with angular form data, make sure you have this in your component.html
Upload Documents
<div class="row">
<div class="col-md-4">
<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">
<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">
<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">
<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>
In your componenet.ts file
declare array selected files like this
selectedFiles = [];
// array of selected files
onFileSelected(event, type) {
this.selectedFiles.push({ type, file: event.target.files[0] });
}
//in the upload files method, append your form data like this
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)
);
}
NOTE: I hope this solution works for you friends
let fd = new FormData();
fd.append( "images" , image1 );
fd.append( "images" , image2 );
fd.append( "images" , image3 );
In this format you can send multiple file by axios.
But i had some problem with this.
only one file was uploaded when i try to append in form data and try to send this through axios.
and my problem was that i had imported {Axios} from 'axios'
but it will not gonna work.
we have to import axios from 'axios'
( look at the spelling )
then it was work perfectly for me
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;
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;
Appending multiple files to the same key didn't work for me. I ended up appending them separately.
files.forEach((file) => {
formData.append(`file-${file.name}`, file);
})
I am trying to upload a file via AJAX and PHP. I have a HTML form as below:
<form method="post" id="sectiononeform" name="sectiononeform" enctype="multipart/form-data">
<div class="clearfix">
<input type="text" name="customHeading1" id="customHeading1" class="span10" value=""/>
</div>
<!-- Gets replaced with TinyMCE, remember HTML in a textarea should be encoded -->
<div class="clearfix">
<textarea id="elm1" name="elm1" rows="15" class="xxlarge" cols="80" style="width: 80%">
</textarea>
</div>
<div class="clearfix">
<input type="file" name="file1" id="file1" class="span10" />
</div>
<div class="clearfix">
<div class="actions">
<input type="submit" id="saveSection1" name="saveSection1" value="Submit" />
<input type="reset" name="resetSection1" value="Reset" />
</div>
</div>
</form>
My jquery code is as follows:
$(document).ready(function(){
$("#saveSection1").click(function(e){
e.preventDefault();
var formdata = false;
/*function showUploadedItem (source) {
var list = document.getElementById("image-list"),
li = document.createElement("li"),
img = document.createElement("img");
img.src = source;
li.appendChild(img);
list.appendChild(li);
} */
if (window.FormData) {
formdata = new FormData();
//document.getElementById("btn").style.display = "none";
}
var len = document.getElementById("file1").files.length, img, reader, file;
for (var i = 0 ; i < len; i++ ) {
file = document.getElementById("file1").files[i];
if (!!file.type.match(/image.*/)) {
if (window.FileReader ) {
reader = new FileReader();
/*reader.onloadend = function (e) {
showUploadedItem(e.target.result, file.fileName);
};*/
reader.readAsDataURL(file);
}
if (formdata) {
alert("form data");
formdata.append("customHeading1", document.getElementById("customHeading1").value);
formdata.append("elm1", document.getElementById("elm1").value);
formdata.append("custsection1", 1);
formdata.append("venue_id", document.getElementById("venue_id").value);
formdata.append("images[]", file);
alert(formdata);
}
}
}
var params = $("form#sectiononeform").serialize();
//alert("params" + params);
params = params + "&custsection1=1&venue_id=" + $("#venue_id").val() + "&formdata=" + formdata;
//alert(params);
$.ajax({
type: 'POST',
url: 'saveCustomSectionData.php',
data: formdata,
success: function(data){
alert(data);
}
});
});
});
My issue is that when I don't use the file input type, I can just serialize the form values and send it through AJAX. Since I am using file input type, I am using formdata and appending information to it. Is this the right way to send data. I am not getting any response back from php, neither can i see any request in firebug. Instead I get some vague error as "Illegal operation on WrappedNative prototype object". Any suggestions?
You can use AJAX to send files. Using new FormData() and the $.ajax method with contentType: false, processData: false.
Check this out:
<script type="text/javascript">
$(document).ready(function()
{
$("#ajax").hide();
$("#botonancho").click(function()
{
if ($("#ficherocsv").val() =="")
{
alert(" Seleccione 1º el archivo ");
}
else
{
var data = new FormData();
data.append( 'file', $( '#ficherocsv' )[0].files[0] );
$("#botonancho").val("Por favor... espere.");
$("#ajax").html("<img src='imagenes/ajax-indicator.gif' alt='Indicador Actividade Ajax' />").show();
$.ajax({
url: 'importacion.php',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data)
{
$("#ajax").html("");
$("#ajax").html(data).fadeIn("slow",function()
{
$("#ajax").delay(1500).fadeOut("slow",function()
{
$("#botonancho").val("IMPORTAR Alumnos CSV (codificación UTF-8)");
$("#ficherocsv").val("");
$("#ajax").hide();
});
});
}
});
}
});
});
</script>
Regards.
so far as i know this is not possible due to security reasons.
but it is possible to use something like jquery.form.js (available from http://jquery.malsup.com/form/) and is quite easy to implement.
they do also provide some nice examples for you to try aswel.