Image Upload to PHP Via Ajax - javascript

I am trying to create an image upload field in my application based on this question:
Send FormData and String Data Together Through JQuery AJAX?
and this tutorial:
http://www.formget.com/ajax-image-upload-php/
I have heard it is quite difficult, this is what i have tried.
HTML
<form method="POST" action="" id="logo_upload">
<input type="file" name="logo_location" id="logo_location" enctype="multipart/form-data">
<button type="submit" name="file_test" id="file_test">Test Upload</button>
</form>
JQuery
$('#logo_upload').submit(function(e) {
e.preventDefault();
var formData = new FormData();
var file_data = $('#logo_location')[0].files[0];
formData.append("file", file_data[0]);
$.ajax({
url: "../../../controllers/ajax_controller.php?action=image_upload",
type: 'POST',
data: formData ,
cache: false,
contentType: false,
processData: false,
id: id
});
});
PHP
var_dump($_FILES);
var_dump($_POST);
As you can see, I haven't got to the uploading side of things yet.
Result
<pre class='xdebug-var-dump' dir='ltr'>
<b>array</b> <i>(size=0)</i>
<i><font color='#888a85'>empty</font></i>
</pre>
<pre class='xdebug-var-dump' dir='ltr'>
<b>array</b> <i>(size=0)</i>
<i><font color='#888a85'>empty</font></i>
</pre>
I can't see what i am doing wrong, I am getting a result so it is getting to the right place, can anyone point me in the right direction?
EDIT: added #logo_upload in form
var file_data = $('#logo_location')[0].files[0];
EDIT: replaced data with formData variable
EDIT: added attribute: enctype="multipart/form-data"
New Result:
<pre class='xdebug-var-dump' dir='ltr'>
<b>array</b> <i>(size=1)</i>
'file' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'undefined'</font> <i>(length=9)</i>
</pre>

You're appending file_data[0] to the formdata object, file_data is the file not an array, use file_data.
$('#logo_upload').submit(function(e) {
e.preventDefault();
var formData = new FormData();
var file_data = $('#logo_location')[0].files[0];
formData.append("file", file_data);
$.ajax({
url: "../../../controllers/ajax_controller.php?action=image_upload",
type: 'POST',
data: formData ,
contentType: false,
processData: false,
success: function(data){
console.log(data);
}
});
});
also you can instantiate the form data object with the form in question instead of doing the append.
$('#logo_upload').submit(function(e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
...

I don't see logo_upload id in your form.
When uploading a file enctype="multipart/form-data" is must in form attributes.
data parameter in your ajax getting a variable i.e. not defined. Look at your reference link once again.
Hope this would help you

You are passing wrong variable here and you are not defining success in your ajax request:
$('#logo_upload').submit(function(e) {
e.preventDefault();
var formData = new FormData($('#your_form_id')[0]);
$.ajax({
url: "../../../controllers/ajax_controller.php?action=image_upload",
type: 'POST',
data: formData,
success: function(result){
alert(result);
}
cache: false,
contentType: false,
processData: false
});
});

Related

Can't get value of input field when using ajax FormData() in Laravel

$(document).on('submit', '#color_changer_form', function(e) {
e.preventDefault();
var colorCode = $('#color_code').val();
var formData = new FormData(this)[0];
$.ajax({
headers: {
'X-CSRF-Token': "{{csrf_token()}}"
},
type: "POST",
url: "{{route('color.store')}}",
data: formData,
async: false,
success: function(data) {
console.log(data)
},
cache: false,
contentType: false,
processData: false
});
});
<form action="" method="POST" id="color_changer_form">
<input type="text" id="color_code" name="color_code">
<button type="submit" id="color_submit" class="btn btn-success">Save Change</button>
</form>
Controller snippet:
public function store(Request $request){
return response()->json($request->all());
}
When I try to get the whole form data using the jQuery AJAX FormData() method, I get an empty array.
In need to use this FormData() because in the near future I have to upload an image using the form data.
Send the whole formData object
Change:
var formData = new FormData(this)[0];
To
var formData = new FormData(this);
If there are no files involved it is simple to use serialize() also
$.ajax({
headers: {
'X-CSRF-Token': "{{csrf_token()}}"
},
type: "POST",
url: "{{route('color.store')}}",
data: $(this).serialize(),
success: function(data) {
console.log(data)
}
});
Never use async:false. it is a terrible practice and is deprecated

Send array of files using AJAX

Say I have an array which contains a few images:
var images = [image1, image2, image3]
How do I send these images to a php file using AJAX in a single request?
The following code did not work:
$.ajax({
url: 'PHP/posts.php',
type: 'post',
data: {data: images},
success: function(data) {
alert(data);
location.reload();
}
});
My HTML:
<div id="newPostFile">
<label for="newPostFiles"><i class="fa fa-file-text-o" id="newPostFileIcon" aria-hidden="true"></i></label>
<input type="file" name="newPostFiles" id="newPostFiles">
</div>
Endgoal:
Whenever a file is selected, the file is added to the array and when the submit button is clicked, all the files are uploaded at once.
You have to send files as formData
var images = [image1, image2, image3]
var data = new FormData();
images.forEach(function(image, i) {
data.append('image_' + i, image);
});
$.ajax({
url: 'PHP/posts.php',
type: 'post',
data: data,
contentType: false,
processData: false,
success: function(data) {
console.log(data);
location.reload();
}
});
But as you're reloading the page anyway, why use ajax at all ?
You can pass a JSON object to PHP, which would be the convenient solution here
var data ={'image1':image1,'image2':image2};
You can pass this object to the php code and then parse it:
Pass the object as a string:
AJAX call:
$.ajax({
type : 'POST',
url : 'PHP/posts.php',
data : {result:JSON.stringify(data)},
success : function(response) {
alert(response);
}
});
You can handle the data passed to the result.php as :
$data = $_POST["result"];
$data = json_decode("$data", true);
//just echo an item in the array
echo "image1 : ".$data["image1"];
Another option would be serializing the array before sending, or convert it into a comma separated string using array.join, then parse/split on the posts.php
array.join(",")
you can just use the list symbol after the input name [i]
for example:
let formData = new FormData();
let files = fileInput.prop('files');
for (let i = 0; i < TotalFiles; i++) {
formData.append('file['+i+']', files[i]);
}
Use FormData Object to send files using ajax.new FormData($('#your_form_id')[0]) automatically appends all form input in FormData object which we can be done by manually formData.append('file1',file1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
let formData = new FormData($('#your_form_id')[0]);
$.ajax({
url: 'PHP/posts.php',
type: 'POST',
data: formData,
dataType:'json',
processData: false,
contentType: false,
success: function(response) {
console.log(response);
location.reload();
},
error: function() {
console.log('fail');
}
});
</script>

Ajax send array and Image in same request

I want to make an ajax call that sends both JSON and file data to my PHP backend. This is my ajax call currently:
$.ajax({
type: 'POST',
dataType: 'json',
data: jsonData,
url: 'xxx.php',
cache: false,
success: function(data) {
//removed for example
}
});
The data(jsonData) is a JSON array that also holds the input from a file select as well(I am assuming this is wrong due to the type mismatch). I tried using contentType: false, and processData: false, but when I try to access $_POST data in PHP there is nothing there. The data I am passing does not come from a form and there is quite a bit of it so I do not want to use FormData and append it to that object. I am hoping i will not have to make two ajax calls to accomplish this.
If you want to send data along with any file than you can use FormData object.
Send your jsonData as like that:
var jsonData = new FormData(document.getElementById("yourFormID"));
Than in PHP, you can check your data and file as:
<?php
print_r($_POST); // will return all data
print_r($_FILES); // will return your file
?>
Try Using formdata instead of normal serialized json
Here's an example:
var formData = new FormData();
formData.append("KEY", "VALUE");
formData.append("file", document.getElementById("fileinputID").files[0]);
then in your ajax
$.ajax({
type: 'POST',
url: "YOUR URL",
data: formData,
contentType: false,
processData: false,
dataType: 'json',
success: function (response) {
CallBack(response, ExtraData);
},
error: function () {
alert("Error Posting Data");
}
});
You can try like this also
You can visit this answer also
https://stackoverflow.com/a/35086265/2798643
HTML
<input id="fuDocument" type="file" accept="image/*" multiple="multiple" />
JS
var fd = new FormData();
var files = $("#fuDocument").get(0).files; // this is my file input in which We can select multiple files.
fd.append("kay", "value"); //As the same way you can append more fields
for (var i = 0; i < files.length; i++) {
fd.append("UploadedImage" + i, files[i]);
}
$.ajax({
type: "POST",
url: 'Url',
contentType: false,
processData: false,
data: fd,
success: function (e) {
alert("success");
}
})

How to pass enctype using JQuery Ajax [duplicate]

This question already has answers here:
Sending multipart/formdata with jQuery.ajax
(13 answers)
Closed 6 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
The XMLHttpRequest Level 2 standard (still a working draft) defines the FormData interface. This interface enables appending File objects to XHR-requests (Ajax-requests).
Btw, this is a new feature - in the past, the "hidden-iframe-trick" was used (read about that in my other question).
This is how it works (example):
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );
where input is a <input type="file"> field, and handler is the success-handler for the Ajax-request.
This works beautifully in all browsers (again, except IE).
Now, I would like to make this functionality work with jQuery. I tried this:
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.post( 'http://example.com/script.php', fd, handler );
Unfortunately, that won't work (an "Illegal invocation" error is thrown - screenshot is here). I assume jQuery expects a simple key-value object representing form-field-names / values, and the FormData instance that I'm passing in is apparently incompatible.
Now, since it is possible to pass a FormData instance into xhr.send(), I hope that it is also possible to make it work with jQuery.
Update:
I've created a "feature ticket" over at jQuery's Bug Tracker. It's here: http://bugs.jquery.com/ticket/9995
I was suggested to use an "Ajax prefilter"...
Update:
First, let me give a demo demonstrating what behavior I would like to achieve.
HTML:
<form>
<input type="file" id="file" name="file">
<input type="submit">
</form>
JavaScript:
$( 'form' ).submit(function ( e ) {
var data, xhr;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
xhr.onreadystatechange = function ( response ) {};
xhr.send( data );
e.preventDefault();
});
The above code results in this HTTP-request:
This is what I need - I want that "multipart/form-data" content-type!
The proposed solution would be like so:
$( 'form' ).submit(function ( e ) {
var data;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
success: function ( data ) {
alert( data );
}
});
e.preventDefault();
});
However, this results in:
As you can see, the content type is wrong...
I believe you could do it like this :
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.ajax({
url: 'http://example.com/script.php',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Notes:
Setting processData to false lets you prevent jQuery from automatically transforming the data into a query string. See the docs for more info.
Setting the contentType to false is imperative, since otherwise jQuery will set it incorrectly.
You can send the FormData object in ajax request using the following code,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
});
This is very similar to the accepted answer but an actual answer to the question topic. This will submit the form elements automatically in the FormData and you don't need to manually append the data to FormData variable.
The ajax method looks like this,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
//append some non-form data also
formData.append('other_data',$("#someInputData").val());
$.ajax({
type: "POST",
url: postDataUrl,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(data, textStatus, jqXHR) {
//process data
},
error: function(data, textStatus, jqXHR) {
//process error msg
},
});
You can also manually pass the form element inside the FormData object as a parameter like this
var formElem = $("#formId");
var formdata = new FormData(formElem[0]);
Hope it helps. ;)
There are a few yet to be mentioned techniques available for you. Start with setting the contentType property in your ajax params.
Building on pradeek's example:
$('form').submit(function (e) {
var data;
data = new FormData();
data.append('file', $('#file')[0].files[0]);
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
// This will override the content type header,
// regardless of whether content is actually sent.
// Defaults to 'application/x-www-form-urlencoded'
contentType: 'multipart/form-data',
//Before 1.5.1 you had to do this:
beforeSend: function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("multipart/form-data");
}
},
// Now you should be able to do this:
mimeType: 'multipart/form-data', //Property added in 1.5.1
success: function (data) {
alert(data);
}
});
e.preventDefault();
});
In some cases when forcing jQuery ajax to do non-expected things, the beforeSend event is a great place to do it. For a while people were using beforeSend to override the mimeType before that was added into jQuery in 1.5.1. You should be able to modify just about anything on the jqXHR object in the before send event.
I do it like this and it's work for me, I hope this will help :)
<div id="data">
<form>
<input type="file" name="userfile" id="userfile" size="20" />
<br /><br />
<input type="button" id="upload" value="upload" />
</form>
</div>
<script>
$(document).ready(function(){
$('#upload').click(function(){
console.log('upload button clicked!')
var fd = new FormData();
fd.append( 'userfile', $('#userfile')[0].files[0]);
$.ajax({
url: 'upload/do_upload',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log('upload success!')
$('#data').empty();
$('#data').append(data);
}
});
});
});
</script>
JavaScript:
function submitForm() {
var data1 = new FormData($('input[name^="file"]'));
$.each($('input[name^="file"]')[0].files, function(i, file) {
data1.append(i, file);
});
$.ajax({
url: "<?php echo base_url() ?>employee/dashboard2/test2",
type: "POST",
data: data1,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(function(data) {
console.log("PHP Output:");
console.log(data);
});
return false;
}
PHP:
public function upload_file() {
foreach($_FILES as $key) {
$name = time().$key['name'];
$path = 'upload/'.$name;
#move_uploaded_file($key['tmp_name'], $path);
}
}
You can use the $.ajax beforeSend event to manipulate the header.
…
beforeSend: function(xhr) {
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}
…
See this link for additional information: http://msdn.microsoft.com/en-us/library/ms536752(v=vs.85).aspx
If you want to submit files using ajax use "jquery.form.js"
This submits all form elements easily.
Samples
http://jquery.malsup.com/form/#ajaxSubmit
rough view :
<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>
<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{
information= responseText;
callAjaxtolist();
$("#AddPhotoForm").resetForm();
$("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>');
};
$(document).ready(function(){
$('.add_new_photo_div').live('click',function(){
var options = {success:showResponseAfterAddPhoto};
$("#AddPhotoForm").ajaxSubmit(options);
});
});
</script>
Instead of - fd.append( 'userfile', $('#userfile')[0].files[0]);
Use - fd.append( 'file', $('#userfile')[0].files[0]);

How to send FormData objects with Ajax-requests in jQuery? [duplicate]

This question already has answers here:
Sending multipart/formdata with jQuery.ajax
(13 answers)
Closed 6 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
The XMLHttpRequest Level 2 standard (still a working draft) defines the FormData interface. This interface enables appending File objects to XHR-requests (Ajax-requests).
Btw, this is a new feature - in the past, the "hidden-iframe-trick" was used (read about that in my other question).
This is how it works (example):
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );
where input is a <input type="file"> field, and handler is the success-handler for the Ajax-request.
This works beautifully in all browsers (again, except IE).
Now, I would like to make this functionality work with jQuery. I tried this:
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.post( 'http://example.com/script.php', fd, handler );
Unfortunately, that won't work (an "Illegal invocation" error is thrown - screenshot is here). I assume jQuery expects a simple key-value object representing form-field-names / values, and the FormData instance that I'm passing in is apparently incompatible.
Now, since it is possible to pass a FormData instance into xhr.send(), I hope that it is also possible to make it work with jQuery.
Update:
I've created a "feature ticket" over at jQuery's Bug Tracker. It's here: http://bugs.jquery.com/ticket/9995
I was suggested to use an "Ajax prefilter"...
Update:
First, let me give a demo demonstrating what behavior I would like to achieve.
HTML:
<form>
<input type="file" id="file" name="file">
<input type="submit">
</form>
JavaScript:
$( 'form' ).submit(function ( e ) {
var data, xhr;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
xhr.onreadystatechange = function ( response ) {};
xhr.send( data );
e.preventDefault();
});
The above code results in this HTTP-request:
This is what I need - I want that "multipart/form-data" content-type!
The proposed solution would be like so:
$( 'form' ).submit(function ( e ) {
var data;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
success: function ( data ) {
alert( data );
}
});
e.preventDefault();
});
However, this results in:
As you can see, the content type is wrong...
I believe you could do it like this :
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.ajax({
url: 'http://example.com/script.php',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Notes:
Setting processData to false lets you prevent jQuery from automatically transforming the data into a query string. See the docs for more info.
Setting the contentType to false is imperative, since otherwise jQuery will set it incorrectly.
You can send the FormData object in ajax request using the following code,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
});
This is very similar to the accepted answer but an actual answer to the question topic. This will submit the form elements automatically in the FormData and you don't need to manually append the data to FormData variable.
The ajax method looks like this,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
//append some non-form data also
formData.append('other_data',$("#someInputData").val());
$.ajax({
type: "POST",
url: postDataUrl,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(data, textStatus, jqXHR) {
//process data
},
error: function(data, textStatus, jqXHR) {
//process error msg
},
});
You can also manually pass the form element inside the FormData object as a parameter like this
var formElem = $("#formId");
var formdata = new FormData(formElem[0]);
Hope it helps. ;)
There are a few yet to be mentioned techniques available for you. Start with setting the contentType property in your ajax params.
Building on pradeek's example:
$('form').submit(function (e) {
var data;
data = new FormData();
data.append('file', $('#file')[0].files[0]);
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
// This will override the content type header,
// regardless of whether content is actually sent.
// Defaults to 'application/x-www-form-urlencoded'
contentType: 'multipart/form-data',
//Before 1.5.1 you had to do this:
beforeSend: function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("multipart/form-data");
}
},
// Now you should be able to do this:
mimeType: 'multipart/form-data', //Property added in 1.5.1
success: function (data) {
alert(data);
}
});
e.preventDefault();
});
In some cases when forcing jQuery ajax to do non-expected things, the beforeSend event is a great place to do it. For a while people were using beforeSend to override the mimeType before that was added into jQuery in 1.5.1. You should be able to modify just about anything on the jqXHR object in the before send event.
I do it like this and it's work for me, I hope this will help :)
<div id="data">
<form>
<input type="file" name="userfile" id="userfile" size="20" />
<br /><br />
<input type="button" id="upload" value="upload" />
</form>
</div>
<script>
$(document).ready(function(){
$('#upload').click(function(){
console.log('upload button clicked!')
var fd = new FormData();
fd.append( 'userfile', $('#userfile')[0].files[0]);
$.ajax({
url: 'upload/do_upload',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log('upload success!')
$('#data').empty();
$('#data').append(data);
}
});
});
});
</script>
JavaScript:
function submitForm() {
var data1 = new FormData($('input[name^="file"]'));
$.each($('input[name^="file"]')[0].files, function(i, file) {
data1.append(i, file);
});
$.ajax({
url: "<?php echo base_url() ?>employee/dashboard2/test2",
type: "POST",
data: data1,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(function(data) {
console.log("PHP Output:");
console.log(data);
});
return false;
}
PHP:
public function upload_file() {
foreach($_FILES as $key) {
$name = time().$key['name'];
$path = 'upload/'.$name;
#move_uploaded_file($key['tmp_name'], $path);
}
}
You can use the $.ajax beforeSend event to manipulate the header.
…
beforeSend: function(xhr) {
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}
…
See this link for additional information: http://msdn.microsoft.com/en-us/library/ms536752(v=vs.85).aspx
If you want to submit files using ajax use "jquery.form.js"
This submits all form elements easily.
Samples
http://jquery.malsup.com/form/#ajaxSubmit
rough view :
<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>
<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{
information= responseText;
callAjaxtolist();
$("#AddPhotoForm").resetForm();
$("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>');
};
$(document).ready(function(){
$('.add_new_photo_div').live('click',function(){
var options = {success:showResponseAfterAddPhoto};
$("#AddPhotoForm").ajaxSubmit(options);
});
});
</script>
Instead of - fd.append( 'userfile', $('#userfile')[0].files[0]);
Use - fd.append( 'file', $('#userfile')[0].files[0]);

Categories

Resources