Ajax success function not outputting text sent by Php script - php

I am uploading multiple files with this PHP script below:
<?php
if(isset($_FILES['uploadfile'])){
$total_files = count($_FILES['uploadfile']['name']);
if( $total_files > 0){
for($i=0; $i<$total_files; $i++) {
$file_name = $_FILES['uploadfile']['name'][$i];
$file_size = $_FILES['uploadfile']['size'][$i];
$file_tmp = $_FILES['uploadfile']['tmp_name'][$i];
$file_type = $_FILES['uploadfile']['type'][$i];
$upload_Path = "storage/".$file_name;
//var_dump($file_size);
//die;
if($file_size > 8000000){
echo ('Total upload size must be less than 8 MB.');
die;
}
if($file_tmp == ""){
echo ('There is no file path.');
die;
}
else{
if(!file_exists($upload_Path)){
move_uploaded_file($file_tmp, $upload_Path);
}
else{
$name = pathinfo($file_name, PATHINFO_FILENAME);
$ext = pathinfo($file_name, PATHINFO_EXTENSION);
$new_name = $name.rand().'.'.$ext;
$new_Path = "storage/".$new_name;
move_uploaded_file($file_tmp, $new_Path);
}
}
}
}
die('File uploaded successfully!');
}
?>
but the problem is that whenever an error occurs such as echo ('Total upload size must be less than 8 MB.'); it doesn't get outputed using ajax. But when a successful upload is done it shows File uploaded successfully!.
My AJAX is as follows:
$.ajax({
type:'POST',
url: 'mupld.php',
data: formdata,
processData:false,
contentType:false,
success: function(response){
alert('Success: '+response);
},
error: function(xhr, status, error){
alert('Error: '+status+' '+error);
}
});
On doing a var dump I dont get any output for uploads above 8mb but for below that I get
Success: <pre class='xdebug-var-dump' dir='ltr'><small>int</small> <font color='#4e9a06'>3283515</font>
</pre>

#Jeff Bucket was right, so I edited my answer:
Actually, you should handle those errors in your success callback. The error() callback is reserved for situations where the connection between browser and server just breaks, and the error() parameters expect to handle those kind of situations, for example a typical textStatus error should be 'Not Found' or 'Internal Server Error', but no 'Total upload size must be less than 8 MB.'.
You should return an array with information you can use in the client, and handle that in success(), like:
try{
if(isset($_FILES['uploadfile'])){
$total_files = count($_FILES['uploadfile']['name']);
if( $total_files > 0){
for($i=0; $i<$total_files; $i++) {
$file_name = $_FILES['uploadfile']['name'][$i];
$file_size = $_FILES['uploadfile']['size'][$i];
$file_tmp = $_FILES['uploadfile']['tmp_name'][$i];
$file_type = $_FILES['uploadfile']['type'][$i];
$upload_Path = "storage/".$file_name;
//var_dump($file_size);
//die;
if($file_size > 8000000){
echo json_encode( array('status' => 'failure' , 'msg' => 'Total upload size must be less than 8 MB.') );
die();
}
if($file_tmp == ""){
echo json_encode( array('status' => 'failure' , 'msg' => 'There is no filepath.') );
die;
}
else{
if(!file_exists($upload_Path)){
move_uploaded_file($file_tmp, $upload_Path);
}
else{
$name = pathinfo($file_name, PATHINFO_FILENAME);
$ext = pathinfo($file_name, PATHINFO_EXTENSION);
$new_name = $name.rand().'.'.$ext;
$new_Path = "storage/".$new_name;
move_uploaded_file($file_tmp, $new_Path);
}
}
}
}
echo json_encode( array('status' => 'success' , 'msg' => 'File uploaded succesfully.') );
die();
}
else{
echo json_encode(array("status" => "error" , "msg" => "No file was found when processing uploaded files" ) );
die();
}
}
catch(Exception $ex){
echo json_encode(array('status' => 'error' , 'msg' => 'An unhandled exception raised: ' . $ex->getMessage() ) );
die();
}
finally{
die();
}
Then in your $.ajax() function:
$("#uploadfile").change(function(){
//submit the form here
var files = $("#fileupload")[0];
var formdata = new FormData(files);
$.ajax({
type:'POST',
url: 'mupld.php',
data: formdata,
processData:false,
contentType:false,
success: function(response){
response = JSON.parse(response);
alert(response.msg);
},
error: function(xhr, textStatus, error){
console.log('Error: '+textStatus+' '+error);
}
});
If you specifically want to handle this in the error() callback, you should set the response code of the php script to 500 -or whatever custom code- using header().

Related

Drag and Drop jQuery & Ajax upload file and sending html form data all together

I want to be able to have a user drag and drop a pdf file and have a modal appear for the user to quickly fill out a form about the file. When the user clicks submit, the file and the form data are passed using Ajax to a php file to then have the file upload and the data processed into a DB.
script.js
// On drop calls uploadFile Function and appends to formData object
$("#dropzone").on ('drop', function (e) {
e.preventDefault();
$(this).removeClass('dropzone dragover').addClass('dropzone');
$("#myModal").removeClass("hidden").addClass("visible");
var file = e.originalEvent.dataTransfer.files;
uploadFile(file);
});
var uploadFile = function(files){
formData = new FormData();
formData.append("file", files);
var x;
for (x = 0; x < files.length; x = x + 1){
let file = files[x];
formData.append('files[]', file);
}
};
// On Form submit all data is saved to values and Ajax call to users.php
$("form").on('submit', function(e) {
// e.preventDefault();
var values = $(this).serialize();
$("#myModal").removeClass("visible").addClass("hidden");
url = 'app/forms/users.php'
$.ajax({
type: 'POST',
url: 'app/forms/users.php',
processData: false,
contentType: false,
cache: false,
data: { formData, values },
dataType: 'json',
success: console.log("Done")
});
});
This is where I run into issues. I am able to
console.log(Array.from(formData)) at all points of interaction before the user hits submit. But when the user submits the form it seems the formData vanishes from existence.
users.php
} else if ($_POST['dispatch'] == 'file_upload') {
// Upload File
var_dump($_FILES);
var_dump($_POST);
$errors = [];
$target_dir = 'F:\wamp64\www\blank\dev\uploads/';
$extensions = ['pdf', 'PDF'];
$all_files = count($_FILES['file']['tmp_name']);
for ($i = 0; $i < $all_files; $i++) {
$file_Name = $_FILES['file']['name'][$i];
$file_Tmp = $_FILES['file']['tmp_name'][$i];
$file_Type = $_FILES['file']['type'][$i];
$file_Size = $_FILES['file']['size'][$i];
$tmp = explode('.', $_FILES['file']['name'][$i]);
$file_ext = strtolower(end($tmp));
$file = $target_dir . date('U')."-".basename($file_Name);
if (!in_array($file_ext, $extensions)) {
$errors[] = 'Extension not allowed: ' . $file_Name . ' ' . $file_Type;
}
if ($file_Size > 9000000000000000000) {
$errors[] = 'File size exceeds limit: ' . $file_Name . ' ' . $file_Type;
}
move_uploaded_file($file_Tmp, $file);
if ($errors) print_r($errors);
}
// Process to DB
Currently, the only data I can find is the formData from the form itself. If there is any information that I missed that could be helpful just let me know. Either I need to go about this a different way or I'm just missing something.
Any help is appreciated. Thank you.

Upload on server image html2canvas

I have this js :
$.ajax({
url: 'ajaxfile.php',
type: 'POST',
data: {
image: base64URL
},
success: function(data){
console.log(data);
$.notify("info", "Upload successfully");
},
error: function () {
$.notify("Error on image upload");
}
});
PHP code :
<?php
$image = $_POST['image'];
$location = "src/upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = "screenshot_".uniqid().'.png';
$file = $location . $filename;
file_put_contents($file, $image_base64);
return [
'status' => true
]
?>
The call is done (I saw in browser console) but on console.log I have the code php returned. Seems that nothing happen, the code php is not implemented. Have you an idea ? Thx in advance and sorry for my english
I put an image with the error
file_put_contents() returns false on failure, so you could assign it to a variable and use that to determine your status like so:
<?php
$image = $_POST['image'];
$location = "src/upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = "screenshot_".uniqid().'.png';
$file = $location . $filename;
$imageData = file_put_contents($file, $image_base64);
if ($imageData !== false) {
echo "success";
} else {
http_response_code(500);
die();
}
?>

How to retrieve FormData in Laravel

I am sending formdata from Angular 2 to Laravel API to save the recorded voice from RecordRTC js. Checked the filename, filetype and blob file on console. it is showing. but not able to retrieve on Laravel backend code.
public uploadToServer() {
let blob = this.recordRTC instanceof Blob ? this.recordRTC : this.recordRTC.blob;
let fileType = blob.type.split('/')[0] || 'audio';
let fileName = (Math.random() * 1000).toString().replace('.', '');
if (fileType === 'audio') {
fileName += '.' + (!!navigator.mozGetUserMedia ? 'ogg' : 'wav');
} else {
fileName += '.webm';
}
// create FormData
var formData: FormData = new FormData();
console.log(fileName);
console.log(blob);
console.log(fileType);
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
console.log(formData);
this.recordingService.saveRecording(formData).subscribe(
data => this.saveRecordingSuccess(data),
error => this.saveRecordingFail(error)
);
}
Laravel Code:-
public function saveRecording(Request $request)
{
$fileName = '';
$tempName = '';
$file_idx = '';
if (!empty($_FILES['audio-blob'])) {
$file_idx = 'audio-blob';
$fileName = $_POST['audio-filename'];
$tempName = $_FILES[$file_idx]['tmp_name'];
}
if (empty($fileName) || empty($tempName)) {
if(empty($tempName)) {
echo 'Invalid temp_name: '.$tempName;
return;
}
echo 'Invalid file name: '.$fileName;
return;
}
$filePath = public_path('voiceRecording/' . $fileName);
// make sure that one can upload only allowed audio/video files
$allowed = array(
'webm',
'wav'
);
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
if (!$extension || empty($extension) || !in_array($extension, $allowed)) {
echo 'Invalid file extension: '.$extension;
return;
}
if (!move_uploaded_file($tempName, $filePath)) {
// error code
return;
}
}
In laravel code I have not receiving any files and post data.
You have to put on your form the mime type, like in JQuery Ajax, have the property
mimeType: "multipart/form-data"

Detecting file type for file upload through AJAX in php

I am having trouble detecting the file type of files when I try to upload them using jQuery ajax ,
Here is how I upload a file using jQuery:
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]); //my file input
//Header require for the framework I am using
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'POST',
url: window.location.origin+'/'+'dataset/create/'+project.pid,
data:formData,
processData:false,//needs to be false for else jQuery gives illegal invocation
contentType:false,
mimeType:"multipart/form-data",
success: function (data) {
uploadDataCallback(data);
},
error: function (data) {
console.error('Error:', data);
}
});
Here is how I handle I try to figure out the file type in php ,
// Check MIME Type .
$finfo = new finfo(FILEINFO_MIME_TYPE);
//var_dump($finfo->file($_FILES['file']['tmp_name'])); //THIS IS ALWAYS 'text/plain'
if (false === $ext = array_search(
$finfo->file($_FILES['file']['tmp_name']),
array(
'csv' => 'text/csv',
'json' => 'application/json',
'csv' =>'text/plain',
),
true
)) {
throw new Exception('Invalid file format.');
}
$finfo always gives 'text/plain' for any type of file i.e. csv ,json etc. I want to detect when user uploads a json file or a csv file so I can parse them appropriately
Here is the entire function for reference:
function create($pid){
$tmpName = $_FILES['file']['tmp_name'];
$file = file($tmpName);
//uploading a file
try {
// Undefined | Multiple Files | $_FILES Corruption Attack
// If this request falls under any of them, treat it invalid.
if(!isset($_FILES['file']) || !is_uploaded_file($_FILES['csv']['tmp_name'][0])){
throw new Exception('File missing');
}
if (
!isset($_FILES['file']['error']) ||
is_array($_FILES['file']['error'])
) {
throw new Exception('Invalid parameters.');
}
// Check $_FILES['file']['error'] value.
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new Exception('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new Exception('Exceeded filesize limit.');
default:
throw new Exception('Unknown errors.');
}
//check filesize here.
if ($_FILES['file']['size'] > 1000000) {
throw new Exception('Exceeded filesize limit.');
}
///////////////THIS IS WHERE IS ALWAYS SAYS 'text/plain' EVEN IF IT IS A JSON FILE
// Check MIME Type .
$finfo = new finfo(FILEINFO_MIME_TYPE);
//var_dump($finfo->file($_FILES['file']['tmp_name'])); //this is always text/plain
if (false === $ext = array_search(
$finfo->file($_FILES['file']['tmp_name']),
array(
'csv' => 'text/csv',
'json' => 'application/json',
'csv' =>'text/plain',
),
true
)) {
throw new Exception('Invalid file format.');
}
// name it uniquely.
// obtain safe unique name from its binary data.
$path=sha1_file($_FILES['file']['tmp_name']);
//dev config
if (!move_uploaded_file(
$_FILES['file']['tmp_name'],
sprintf(base_path().'/public/devStorage/%s.%s',
$path,
$ext
)
)) {
throw new Exception('Failed to move uploaded file.');
}
if($ext=='csv'){
$csvAsArray = array_map('str_getcsv', $file);
//dd($csvAsArray);
$rows=count($csvAsArray);
//everything fine,file is uploaded succesfully
//save dataset
$dataset=new DataSet;
$dataset->name=$_FILES['csv']['name'];
$dataset->iduser=Auth::user()->iduser;
$dataset->pid=$pid;
$dataset->path=$path;
$dataset->type=$ext;
$dataset->rows=$rows;
$dataset->cols=count($csvAsArray[0]);
$dataset->save();
for($i=0;$i<count($csvAsArray[0]);$i++ ){
$datasetCol=new DataSetColumn;
$datasetCol->col_name=$csvAsArray[0][$i]; //first row is assume to be the header row
if(is_numeric($csvAsArray[1][$i])){ //second row is taken as value and its type is assumed for entire column
$datasetCol->col_type='Number';
}
else{
$datasetCol->col_type='String';
}
$datasetCol->iddata_sets=$dataset->iddata_sets;
$datasetCol->save();
}
return json_encode($dataset);
}
else if($ext=='json'){
dd('jsonff');
}
} catch (Exception $e) {
$message='Error:'.$e->getMessage();
return $message;
}
}

Form not sending files other than images

I'm trying to upload files using php and I am copying and renaming files from other instances that are actually working (uploading pics). But for some reason the form is not passing (POST) any file that is NOT an image :-/
So, in resume, I am getting this (Google) 'request payload' for an image file:
------WebKitFormBoundaryrHOYostaC2KnUDlD
Content-Disposition: form-data; name="uploaded_file[]"; filename="image.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryrHOYostaC2KnUDlD--
But this for txt or pdf files:
------WebKitFormBoundaryc1RJOtSOpYKAZiBz--
Here is the form and script (functions are to avoid the user to click 'Submit', those work good):
echo '
<script language="JavaScript" type="text/javascript">
function HandleBrowseClick()
{
var fileinput = document.getElementById("uploaded_file");
fileinput.click();
}
function Handlechange()
{
var fileinput = document.getElementById("uploaded_file");
var textinput = document.getElementById("filename");
textinput.value = fileinput.value;
}
</script>';
echo '
<form enctype="multipart/form-data" target="_blank" name="send_file" id="send_file" method="post" action="file_upload.php">
<input type="file" class="hide button" id="uploaded_file" name="uploaded_file" onChange="Handlechange();"/>
<button type="submit" id="btn">Upload!</button>
</form>';
echo '
<div onclick="HandleBrowseClick();" id="fakeBrowse" >Load a file</div>
<input type="text" id="filename" size="50" readonly="true" />
';
So, since it's not passing anything, in my file_upload.php I get the "ERROR: Please browse for a file before clicking the upload button." or "Invalid argument supplied for foreach()" (if I expect an array) error.
I tried using application/x-www-form-urlencoded allowing the same result. Now for those who get mad if there is no question marks: Why the form works fine with images but not so with other kind of files? What am I dong wrong?
Here is the first few lines of file_upload.php (I don't think it's necessary but you never know):
$target = "../files/temp/";
foreach ($_FILES["uploaded_file"]["error"] as $key => $error) {
if ($error != UPLOAD_ERR_OK) { echo "error"; die;}
$fileName = $target . $_FILES["uploaded_file"]["name"][$key]; // The file name
$fileTmpLoc = $_FILES["uploaded_file"]["tmp_name"][$key]; // File in the PHP tmp folder
$fileType = $_FILES["uploaded_file"]["type"][$key]; // The type of file it is
$fileSize = $_FILES["uploaded_file"]["size"][$key]; // File size in bytes
$fileErrorMsg = $_FILES["uploaded_file"]["error"][$key]; // 0 for false... and 1 for true last $key!!!
$fileName = preg_replace('#[^a-z.0-9]#i', '', $fileName); // filter the $filename
$fileName = strtolower($fileName);
$kaboom = explode(".", $fileName); // Split file name into an array using the dot
$fileExt = end($kaboom); // Now target the last array element to get the file extension
if (!$fileTmpLoc) { // if file not chosen
echo "ERROR: Please browse for a file before clicking the upload button.";
exit();
}
else if ($fileErrorMsg == 1) { // if file upload error key is equal to 1
echo "ERROR: An error occurred while processing the file. Try again.";
exit();
}
Finally, some more js:
if (window.FormData) {
formdata = new FormData();
document.getElementById("btn").style.display = "none";
}
input.addEventListener("change", function (evt) {
document.getElementById("response").innerHTML = "Loading . . ."
var i = 0, len = this.files.length, img, reader, file;
for ( ; i < len; i++ ) {
file = this.files[i];
if (!!file.type.match(/image.*/)) {
if (formdata) {
formdata.append("uploaded_file[]", file);
}
}
}
if (formdata) {
$.ajax({
url: "file_upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false
}).done(function (res) {
document.getElementById("response").innerHTML = res;
if ( window.FileReader ) {
reader = new FileReader();
reader.onloadend = function (e) {
showUploadedItem(e.target.result, file.fileName);
};
reader.readAsDataURL(file);
}
});
}
}, false);
where changing contentType doesn't make any diference
THANKS!!!
You have to define the MIME types for your files. For example
.pdf application/pdf
.doc application/msword
Okay, my bad. The js file has an image filter. It started working right away after I removed it.

Categories