Ajax File Uploads - php

I have the following form:
<form method="post" enctype="multipart/form-data" id="upload" action="upload.php">
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>
</form>
The following Javascript:
$(document).ready(function () {
$("#uploadbutton").click(function () {
var filename = $("#file").val();
$.ajax({
type: "POST",
url: "upload.php",
enctype: 'multipart/form-data',
data: {
file: filename
},
success: function (text) {
alert("Data Uploaded: " + text);
}
});
});
});
and the following PHP (as a test)
echo json_encode($_POST); //uses post to check as $_FILES returns nothing
the alert will then notify me with the response line "file: test.jpg" as you can see though this is a file name and not the actual file itself. How can i convert my file to get the actual file rather then the name of the file.
Thank you in advance.

You still can use the "PUT" method instead of the "POST" method, it will work for all browsers except the old ones.
See : Topic

The syntax you are using is wrong for uploading files with ajax, you would need to pass a FormData object as the data of the request and use processData: false. However, some browsers don't support FormData, therefore you'll have to fallback to posting to a hidden iframe in those browsers.

Related

i am getting error in php while uploading image to databse using jquery, the data in variables arent passing maybe

My code is a form where it picks a file from the user, then send the data using jQuery to a PHP file where it gets the image content and displays it and in a success function: it alerts the data received from the PHP file. For example, the image received from the HTML page.
Actually, the code inserts the image into the database, but I plucked the code out and inserted a direct view of image in PHP file without inserting in the database because I wanted to make it short(database insertion code has no error: it inserts other variables provided with image and image stays blank)
Also am using my script on XAMPP localhost. So do not worry about that i am running it like file://... . All is that i can't figure out why the data aren't being passed to php file.
HTML:
<input style="border:none" type="file" id="photo" /> <br>
JavaScript:
$("#submit-form").click(function() {
var formadata = {
"photo": $("#photo").val(),
};
$.ajax({
url: './enter-registration-form.php',
data: formadata,
cache: false,
contentType: false,
processData: false,
method: 'POST',
success: function(val) {
if (val == "done") {
alert("Data Accepted");
} else {
alert(val);
}
}
});
});
PHP:
$i = $_FILES['photo']['name'];
//get the content of the image and then add slashes to it
$imagetmp=addslashes (file_get_contents($_FILES['photo']['tmp_name']));
echo '<img src="data:image/jpeg;base64,'.base64_encode($imagetmp).'" style="width:100px;height:autoborder:none">';
Now I am getting this error message:
Notice: Undefined index: photo in
/opt/lampp/htdocs/SSNC/exam/enter-registration-form.php on line 5
Notice: Undefined index: photo in
/opt/lampp/htdocs/SSNC/exam/enter-registration-form.php on line 8
Warning: file_get_contents(): Filename cannot be empty in
/opt/lampp/htdocs/SSNC/exam/enter-registration-form.php on line 8
I can't figure out why this error is thrown.
Approach
You need to use new FormData() object.
The FormData interface provides a way to easily construct a set of
key/value pairs representing form fields and their values, which can
then be easily sent using the XMLHttpRequest.send() method. It uses
the same format a form would use if the encoding type were set to
"multipart/form-data".
So you don't actually have to declare a form tag and add inputs inside, yes it makes it easier if you have let us make a call assuming that you do not have a form tag.
Problem
The problem in your script is that your formdata is a json rather than a FormData() interface object, which uses formdataObject.append() which appends a new value onto an existing key inside a FormData object, or adds the key if it does not already exist.
See code below which posts email, file label and a file to a PHP page without using form tag for the inputs.
Without <form> tag
Assuming that your html looks like below without a form
<label>Your email address:</label>
<input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" />
<br />
<label>Custom file label:</label>
<input type="text" name="filelabel" size="12" maxlength="32" />
<br />
<label>File to stash:</label>
<input type="file" name="file" required />
<input type="button" name="submit" value="Stash the file!" />
Your javascript code will look like below
$(document).ready(function () {
$("input[name='submit']").on('click', function (event) {
event.preventDefault();
//START Append form data
var data = new FormData();
data.append(
'userid', $("input[name='userid']").val());
data.append(
'label', $("input[name='filelabel']").val()
);
data.append('file', $("input[name='file']")[0].files[0], 'somename.jpg');
//END append form data
$.ajax({
type: "POST",
url: "file.php",
data: data,
processData: false,
contentType: false,
success: function (data) {
console.log("SUCCESS : ", data);
},
error: function (e) {
console.log("ERROR : ", e);
}
});
});
});
And your file.php will look like below
<?php
print_r($_POST);
print_r($_FILES);
This should show you the file inputs and file both of them in the console when you hit the stash file button.
With <form> tag
If you have the inputs wrapped inside the form tag then your code will be changed on the following sections
Change binding of click event to form submit event.
Change button type to submit in the HTML.
Get the form object.
Use form object to initialize the FormData().
See below How your HTML will look like
<form enctype="multipart/form-data" method="post" name="fileinfo">
<label>Your email address:</label>
<input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" />
<br />
<label>Custom file label:</label>
<input type="text" name="filelabel" size="12" maxlength="32" />
<br />
<label>File to stash:</label>
<input type="file" name="file" required />
<input type="submit" value="Stash the file!" />
</form>
And your javascript will look like below
$(document).ready(function () {
$("form").on('submit', function (event) {
event.preventDefault();
var form = this;
var data = new FormData(form);
$.ajax({
type: "POST",
url: "file.php",
data: data,
processData: false,
contentType: false,
success: function (data) {
console.log("SUCCESS : ", data);
},
error: function (e) {
console.log("ERROR : ", e);
}
});
});
});
This should work!
HTML:
<form id="my-upload-form" method="post" enctype="multipart/form-data">
<input type="file" name="required-image" />
<button> Upload </button>
</form>
JS:
$("button").click(function(e) {
/* prevent default form action */
e.preventDefault();
/* get form element */
var formElement = document.getElementById("my-upload-form");
/* collect all form data from Form element */
var formData = new FormData(formElement);
$.ajax({
url: '/path-to-form-handler.php',
data: formData,
cache: false,
contentType: false,
processData: false,
method: 'POST',
success: function(response) {
console.log(response);
}
});
});
PHP:
<?php
/* for this example, $_FILES["required-image"] would be an array having image details */
echo $_FILES["required-image"]["name"];
echo $_FILES["required-image"]["type"];
echo $_FILES["required-image"]["tmp_name"];
echo $_FILES["required-image"]["size"];
?>
First of all insert your input file tag in a form and use enctype="multipart/formdata"
to send an image otherwise you will not able to send image

File upload fails when using ajax submit with return false

I have a form that has a simple file input.
<form id="uploadFile" name="uploadFile" action="addFile.php" method="POST" enctype="multipart/form-data">
<input type="hidden" value="" name="uploadWUID" id="uploadWUID">
<p>Please upload a signed and completed write-up in PDF format. Please file the hardcopy of the write-up per company policy.</p>
<div class="input-group" style="margin-bottom:7px;">
<span class="input-group-btn">
<span class="btn btn-primary btn-file">
Browse… <input type="file" id="reportImport" name="reportImport">
</span>
</span>
<input type="text" class="form-control" readonly>
</div>
</form>
There is some local javascript that puts the filename in the text input, but the text input is not used in the PHP file.
The uploadWUID is set dynamically and is passed to add the uploaded file to a specific record in a database.
When I submit the form it works just fine. My browser redirects to addFile.php, success is echoed out, the file is moved to the correct directory and the database is updated.
My issues comes when I add return false to my ajax form submission. I get an error back from the php file stating it couldn't find the index when processing $filename = $_FILES['reportImport']['name']; and my upload/database update fails.
$('#uploadFile').submit(function() {
$.ajax({
data: $(this).serialize(),
type: $(this).attr('method'),
url: $(this).attr('action'),
success: function(response) {}
});
return false;
});
Change script code
$('#uploadFile').submit(function() {
var formData = new FormData($(this)[0]);
$.ajax({
data: formData,
type: $(this).attr('method'),
url: $(this).attr('action'),
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
success: function(response) {
console.log(response);
alert(response);
return false
}
});
return false;
});

Ajax large-ish file upload with FormData and jQuery fails to post the data

I am trying to upload files via AJAX using FormData. If I submit the AJAX call without selecting any files to upload, the post works fine, and other fields (that are not file uploads) are received on the server OK. If I select a file to upload though, the call arrives at the server with no data whatsoever (in PHP, the $_POST and $_FILES arrays are both completely empty). I understand this can happen if you fail to tell jQuery not to set the contentType, but I am setting contentType and processData to false and it still won't send the data.
Here is my code:
function AddComment(taskid) {
var newnote = $('#newnote_'+taskid).val();
if(newnote != '') {
$('#tasklist *').css('cursor', 'progress');
var formData = new FormData();
$('.upload-' + taskid).each(function() {
if (this.files[0]) {
formData.append($(this).attr('name'), this.files[0]);
}
});
formData.append("taskid", taskid);
formData.append("newnote", newnote);
$.ajax({
url: '/modules/task/ajax/ajaxAddComment.php',
data: formData,
processData: false,
contentType: false,
type: 'post',
success: function(data){
alert(data);
}
});
}
}
I'm sure I'm doing something stupid, but I can't see what...?
Edit: Here is the HTML:
<form id="frmNewComment544" enctype="multipart/form-data" method="post" action="">
<div>
<textarea style="width:100%;" cols="30" rows="5" id="newnote_544"></textarea>
</div>
<div>
<input type="button" onclick="AddComment(544)" value="Append Comment">
</div>
<div class="attachment-browsers" id="attachmentBrowsers544" style="display: block;">Attachments will be uploaded when you append a comment.
<div>
<input type="file" id="upload_544_151ab3cfe69" name="upload_544_151ab3cfe69" class="upload-544">
</div>
<div>
<input type="file" id="upload_544_3y4afe6eg7a" name="upload_544_3y4afe6eg7a" class="upload-544">
</div>
</div>
</form>
Edit 2: OK, the problem only occurs when uploading relatively large files (not massive - in this case it was 10MB). Small files upload OK. So now the question is why I cannot upload large files using this method?
I knew it would be something stupid!
My php.ini had the default 2MB limit for file uploads. D'oh.
I don't see any reference to your form.
May be you would do it like this:
.....
var form = $('form#frmNewComment544');
var formdata = false;
if (window.FormData){
formdata = new FormData(form[0]);
}
var formAction = form.attr('action');
$.ajax({
url: formAction,
data : formdata ? formdata : form.serialize(),
....

Upload files with Ajax and Jquery

I've been trying to figure out how to upload a file through ajax for the past several hours and nothing.
Here's the code:
HTML:
<form action="" method="post" id="uploadForm" enctype="multipart/form-data">
<input type="file" name="image" id="image">
<input type="submit">
</form>
JS:
<script>
jQuery(document).ready(function(){
jQuery('form#uploadForm').on('submit', function(e){
e.preventDefault();
var file = jQuery('#image')[0].files[0];
var form_data = new FormData( jQuery("form#uploadForm")[0] );
form_data.append( 'image', file );
jQuery.ajax({
url: 'index.php?a=do',
type: 'POST',
processData: false,
contentType: false,
cache: false,
data: form_data,
success: function(response) {
console.log(response);
},
});
return false;
});
});
</script>
PHP:
<?php
$a = isset($_GET['a']) ? $_GET['a'] : '';
if($a <> '') {
echo "result - ";
var_dump($_POST);
die();
}
?>
As a result I get an empty array, however if I leave the file field empty, then I get:
result - array(1) {
["image"]=>
string(9) "undefined"
}
I've tried serialize(), serializeObject(), serializeArray(), $.param and every damn time I get "undefined function" error in console.
I went through dozens of similar questions on stackoverflow and nothing helped. I tried doing $.post instead of $.ajax and the "data" field which contains form_data is empty.
I need this for a Wordpress plugin and I'm trying to avoid using 3rd party JS plugins for the upload part.
$_FILES is where you check for uploaded files not $_POST.
Also in your code you actually upload the file twice as it is in the form you instantiated the form data object with then you add it again with append.
Do either
var form_data = new FormData( jQuery("form#uploadForm")[0] );
or
var form_data = new FormData();
form_data.append( 'image', file );
<html>
<head>
<title>Ajax file upload</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function (e) {
$("#uploadimage").on('submit',(function(e) {
e.preventDefault();
$.ajax({
url: "ajax_php_file.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data) // A function to be called if request succeeds
{
alert(data);
}
});
}));
</script>
</head>
<body>
<div class="main">
<h1>Ajax Image Upload</h1><br/>
<hr>
<form id="uploadimage" action="" method="post" enctype="multipart/form-data">
<div id="image_preview"><img id="previewing" src="noimage.png" /></div>
<hr id="line">
<div id="selectImage">
<label>Select Your Image</label><br/>
<input type="file" name="file" id="file" required />
<input type="submit" value="Upload" class="submit" />
</div>
</form>
</div>
</body>
</html>

Working with input type file AJAX/PHP

I have got this html/php in my index.php
if (isset($_POST['UploadMSub'])) {
$fileP=$_FILES['Upload_f'];
$fileP_name=$fileP['name'];
$fileP_tmp=$fileP['tmp_name'];
$fileP_size=$fileP['size'];
$fileP_error=$fileP['error'];
$fileP_extension=explode('.', $fileP_name);
$fileP_extension=strtolower(end($fileP_extension));
$allowed=array('jpg','png');
if (in_array($fileP_extension, $allowed)) {
if ($fileP_error===0) {
if ($fileP_size<=2097152) {
$fileP_new_name=uniqid().'.'.$fileP_extension;
}
}
}
$_SESSION['fileP']=$fileP;
$_SESSION['fileP_name']=$fileP_name;
$_SESSION['fileP_tmp']=$fileP_tmp;
$_SESSION['fileP_size']=$fileP_size;
$_SESSION['fileP_error']=$fileP_error;
$_SESSION['fileP_extension']=$fileP_extension;
$_SESSION['fileP_new_name']=$fileP_new_name;
}
<form method="post" enctype="multipart/form-data" class='SubmUploadFu'>
<textarea maxlength="400" type="text" class='Text' placeholder="New post"></textarea>
<input type="file" name="Upload_f" style="display:none;" id="Nameupload">
<label for="Nameupload" class='LabelCamerUp'>
<img src="../img/camera.png" class='CamerUp'>
</label>
<input type="submit" class="UploadMSub">
</form>
And this ajax
$(".UploadMSub").click(function() {
var text=$(".Text").val();
var file=$("#Nameupload").val();
$.ajax({
type: "GET",
url: '../connect.php',
data: "Text=" + text+"&&file="+file,
success: function(data)
{
alert(data);
}
});
return false;
});
connect.php
if (isset($_GET['Text'])) {
$Text=htmlspecialchars($_GET['Text'],ENT_QUOTES);
$file=htmlspecialchars($_GET['file'],ENT_QUOTES);
echo $Text." ".$_SESSION['fileP_new_name'];
}
But when i submit form it returns(alerts)
"Undefine index ''fileP_new_name'"
Is there any other way of getting all information about file in my connect.php?
The problem is,
When you hit the submit button, the form doesn't get submitted, which means none of your session variables are set when you hit the submit button. Instead jQuery script runs straight away when you hit the submit button, and that's why you're getting this error,
Undefine index: fileP_new_name
From your question,
Is there any other way of getting all information about file in my connect.php?
So the solution is as follows. You have to change few things in your code, such as:
Add a name attribute in your <textarea> element, like this:
<textarea maxlength="400" name="new_post" class='Text' placeholder="New post"></textarea>
Instead of returning false from your jQuery script, use preventDefault() method to prevent your form from being submitted in the first place, like this:
$(".UploadMSub").click(function(event){
event.preventDefault();
// your code
});
If you're uploading file through AJAX, use FormData object. But keep in mind that old browsers don't support FormData object. FormData support starts from the following desktop browsers versions: IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+.
Set the following options, processData: false and contentType: false in your AJAX request. Refer the documentation to know what these do.
So your code should be like this:
HTML:
<form method="post" enctype="multipart/form-data" class='SubmUploadFu'>
<textarea maxlength="400" name="new_post" class='Text' placeholder="New post"></textarea>
<input type="file" name="Upload_f" style="display:none;" id="Nameupload">
<label for="Nameupload" class='LabelCamerUp'>
<img src="../img/camera.png" class='CamerUp'>
</label>
<input type="submit" class="UploadMSub">
</form>
jQuery/AJAX:
$(".UploadMSub").click(function(event){
event.preventDefault();
var form_data = new FormData($('form')[0]);
$.ajax({
url: '../connect.php',
type: 'post',
cache: false,
contentType: false,
processData: false,
data: form_data,
success: function(data){
alert(data);
}
});
});
And on connect.php, process your form data like this:
<?php
if(is_uploaded_file($_FILES['Upload_f']['tmp_name']) && isset($_POST['new_post'])){
// both file and text input is submitted
$new_post = $_POST['new_post'];
$fileP=$_FILES['Upload_f'];
$fileP_name=$fileP['name'];
$fileP_tmp=$fileP['tmp_name'];
$fileP_size=$fileP['size'];
$fileP_error=$fileP['error'];
$fileP_extension=explode('.', $fileP_name);
$fileP_extension=strtolower(end($fileP_extension));
$allowed=array('jpg','png');
if (in_array($fileP_extension, $allowed)){
if ($fileP_error===0) {
if ($fileP_size<=2097152){
$fileP_new_name=uniqid().'.'.$fileP_extension;
}
}
}
// your code
//echo $fileP_new_name;
}
?>

Categories