php ajax file upload, $_FILE is empty - javascript

I have a blob object and some data need to be post to fileHandler.php
so I pack them into a FormData:
console.log("start saving");
var url1 = URL.createObjectURL(blob);
var url2 = "data:application/octet-stream," + encodeURIComponent(JSON.stringify(dataPack));
console.log(url1);
console.log(url2);
fd.append('realName', dataPack.name);
fd.append("ans", JSON.stringify(dataPack.ans));
fd.append("log", JSON.stringify(dataPack.log));
fd.append("part", dataPack.part);
fd.append('fileToUpload', blob);
window.postData = fd;
and upload them via ajax:
$.ajax({
type: 'POST',
url: '../php/fileHandler.php',
data: postData,
processData: false,
contentType: false,
success: function() {
uploadSuccess();
},
error: function() {
uploadFail();
},
progress: function(e) {
console.log(e);
//make sure we can compute the length
if(e.lengthComputable) {
//calculate the percentage loaded
var pct = parseInt((e.loaded / e.total) * 100);
//log percentage loaded
$('#uploadProgress').width(pct+"%").text(pct+"%");
console.log(pct);
}
//this usually happens when Content-Length isn't set
else {
console.warn('Content Length not reported!');
}
}
}).done(function(data) {
console.log(data);
if(data ==="ok") {
uploadSuccess();
}
else {
uploadFail();
}
});
php file handler:
<?php
$target_dir = "uploads/";
$realName = trim($_POST['realName']);
$part = $_POST['part'];
$ans = json_decode($_POST['ans']);
$log = json_decode($_POST['log']);
$fileNameNoEx = $target_dir . $realName . "-" . $part ."-". time();
$target_file = $fileNameNoEx . ".mp3";
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
//save files
$f = fopen($fileNameNoEx.".txt", "w");
fwrite($f, "Answer log:\n");
foreach ($ans as $page => $val) {
fwrite($f, "$page : $val\n");
}
fwrite($f, "\nPage switching event log:\n");
foreach ($log as $l) {
fwrite($f, "{$l->time}s ---> {$l->page}\n");
}
fclose($f);
echo "ok";
} else {
var_dump($ans);
var_dump($log);
var_dump($_POST);
var_dump($_FILES);
var_dump($target_file);
echo "asdsad";
echo "Sorry, there was an error uploading your file.";
}
}
then strange things happen, sometimes uploading failed, and I when I try to upload again(in console, with the same data), browser keep logging:
NULL
NULL
array(0) {
}
array(0) {
}
string(24) "uploads/--1500100885.mp3"
asdsadSorry, there was an error uploading your file.
it seems that postData is empty? But when I check the postData in browser console:
> postData.get("fileToUpload")
File {name: "blob", lastModified: 1500101804839, lastModifiedDate: Sat Jul 15 2017 14:56:44 GMT+0800 (China Standard Time), webkitRelativePath: "", size: 12597888…}
> postData.get("realName")
"jjj"
why???? how can $_FILES[] and $_POST[] be emtpy?
This problem happens often when the file is very large.

PHP has a maximum post size, try to increase it: Increasing the maximum post size
If PHP didn't have this limit I could send an infinitely large POST to your web server until either it runs out of disk or RAM.

Related

Uploading Picture Is Corrupted

I am trying to allow users to upload a new profile pic by clicking on the old one.
I am using ajax and a file reader to do so
$('#profileImage').click(function(){ $('#image-file').trigger('click'); });
$('#image-file').on('change',function(){
if (this.files && this.files[0]) {
var FR= new FileReader();
FR.readAsDataURL(this.files[0]);
FR.addEventListener("load", function(e) {
document.getElementById("profileImage").src = e.target.result;
imgData = e.target.result;
var formData = {
'name' : localStorage.getItem('email'),
'image' : imgData
};
console.log("image data: " + imgData);
$.ajax({
type : 'POST',
url : '/uploadprofile.php',
data : formData,
dataType: 'text',
encode : true
}).done(function(data) {
console.log(data);
});
});
}
});
The new image is loaded onto the old picture and the console tracks the image data sent through.
The only issue is that the newly updated picture is not visible to the container. It shows an icon of a broken picture.
This is my php file that handles the insertion
$json = json_decode(file_get_contents('php://input'),true);
if ($json == "") {
$name = $_POST['name'];
$image = $_POST['image'];
} else {
$name = $json["name"]; //within square bracket should be same as Utils.imageName & Utils.image
$image = $json["image"];
}
$response = array();
$decodedImage = base64_decode("$image");
//unlink old picture
// unlink($name.".jpg");
$oldName = $name;
$name .= date("D M d Y G:i");
$name = str_replace(' ', '', $name);
$fullPath = "http://www.mywebsite.com/uploads/".$name.".jpg";
$return = file_put_contents("uploads/".$name.".jpg", $decodedImage);
if($return !== false){
$response['email'] = $oldName;
$response['image'] = $image;
$response['success'] = 1;
$response['message'] = "Image Uploaded Successfully";
$sql = "UPDATE Users SET PicLocation = '$fullPath' WHERE Email = '$oldName'";
$result = $conn->query($sql);
}else{
$response['success'] = 0;
$response['message'] = "Image Uploaded Failed";
}
echo json_encode($response);
The value for $response['image'] that gets printed out is correct but it doesn't seem to show the picture. The data is corrupted somehow. Is there something I should do to get the correct data?
Additionally, sometimes I get the error:
jquery.min.js:2 POST http://tanglecollege.com/uploadprofile.php 406 (Not Acceptable)
I don't know what it means and there doesn't seem to be a good explanation.
Also, the file that gets saved to the server is corrupted in some way. I can track the base64 data being passed along from js to php but when it is saved as a file, that file is corrupted and the image can not be read from the filepath.

How to play audio file using ajax when it return to php variable

I am trying to play music dynamically from ajax response data but the problem is how to play audio file when it return to php variable?
I am using mediaelement.js pluging for audio player.
JAVASCRIPT
var player = new MediaElementPlayer('audio-player', {
//options
});
$.ajax({
url: '../play?song=songs_id',
type: "get",
success:function(data){
player.pause();
player.setSrc(data);
player.load();
player.play();
}
});
PHP
$song_id = 'folder/'.$_GET['song'];
// get the file request, throw error if nothing supplied
// hide notices
#ini_set('error_reporting', E_ALL & ~ E_NOTICE);
//- turn off compression on the server
#apache_setenv('no-gzip', 1);
#ini_set('zlib.output_compression', 'Off');
// sanitize the file request, keep just the name and extension
// also, replaces the file location with a preset one ('./myfiles/' in this example)
$file = $song_id;
$path_parts = pathinfo($file);
$file_name = $path_parts['basename'];
$file_ext = $path_parts['extension'];
$file_path = $song_id;
// allow a file to be streamed instead of sent as an attachment
$is_attachment = isset($_REQUEST['stream']) ? false : true;
// make sure the file exists
if (is_file($file_path))
{
$file_size = filesize($file_path);
$file = #fopen($file_path,"rb");
if ($file)
{
// set the headers, prevent caching
header("Pragma: public");
header("Expires: -1");
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
header("Content-Disposition: attachment; filename=\"$file_name\"");
// set appropriate headers for attachment or streamed file
if ($is_attachment) {
header("Content-Disposition: attachment; filename=\"$file_name\"");
}
else {
header('Content-Disposition: inline;');
header('Content-Transfer-Encoding: binary');
}
// set the mime type based on extension, add yours if needed.
$ctype_default = "application/octet-stream";
$content_types = array(
"exe" => "application/octet-stream",
"zip" => "application/zip",
"mp3" => "audio/mpeg",
"mpg" => "video/mpeg",
"avi" => "video/x-msvideo",
);
$ctype = isset($content_types[$file_ext]) ? $content_types[$file_ext] : $ctype_default;
header("Content-Type: " . $ctype);
//check if http_range is sent by browser (or download manager)
if(isset($_SERVER['HTTP_RANGE']))
{
list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if ($size_unit == 'bytes')
{
//multiple ranges could be specified at the same time, but for simplicity only serve the first range
//http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
list($range, $extra_ranges) = explode(',', $range_orig, 2);
}
else
{
$range = '';
header('HTTP/1.1 416 Requested Range Not Satisfiable');
exit;
}
}
else
{
$range = '';
}
//figure out download piece from range (if set)
list($seek_start, $seek_end) = explode('-', $range, 2);
//set start and end based on range (if set), else set defaults
//also check for invalid ranges.
$seek_end = (empty($seek_end)) ? ($file_size - 1) : min(abs(intval($seek_end)),($file_size - 1));
$seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);
//Only send partial content header if downloading a piece of the file (IE workaround)
if ($seek_start > 0 || $seek_end < ($file_size - 1))
{
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$file_size);
header('Content-Length: '.($seek_end - $seek_start + 1));
} else {
}
header("Content-Length: $file_size");
header('Accept-Ranges: bytes');
set_time_limit(0);
fseek($file, $seek_start);
while(!feof($file))
{
print(#fread($file, 1024*8));
ob_flush();
flush();
if (connection_status()!=0)
{
#fclose($file);
exit;
}
}
// file save was a success
#fclose($file);
exit;
}
else
{
// file couldn't be opened
header("HTTP/1.0 500 Internal Server Error");
exit;
}
}
else
{
// file does not exist
header("HTTP/1.0 404 Not Found");
exit;
}
If i set player.setSrc(data); to player.setSrc('../play?song=songs_id'); then it worked fine but i don't want that. Any idea?
Your PHP code is doing all the work to process the desired URL, and you are basically using play?song=songs_id to set headers and send the file via this piece of code:
print(#fread($file, 1024*8));
ob_flush();
flush();
if (connection_status()!= 0)
{
#fclose($file);
exit;
}
As you can see, you are not using any return statement so you can use that URL to play your media. You are trying to even read the media through PHP. That's why if you use player.setSrc('../play?song=songs_id'); your code will work

convert php image upload script to json response

I wrote the script for uploading image in folder say (upload) in my case.
It's working perfectly !
I just want to get response message in json.
I don't know how to use json in scrip and where.
Thanks !
script.js
$(document).ready(function (e) {
$("#uploadimage").on('submit',(function(e) {
e.preventDefault();
$("#message").empty();
$('#loading').show();
$.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
{
$('#loading').hide();
$("#message").html(data);
}
});
}));
// Function to preview image after validation
$(function() {
$("#file").change(function() {
$("#message").empty(); // To remove the previous error message
var file = this.files[0];
var imagefile = file.type;
var match= ["image/jpeg","image/png","image/jpg"];
if(!((imagefile==match[0]) || (imagefile==match[1]) || (imagefile==match[2])))
{
$('#previewing').attr('src','noimage.png');
$("#message").html("<p id='error'>Please Select A valid Image File</p>"+"<h4>Note</h4>"+"<span id='error_message'>Only jpeg, jpg and png Images type allowed</span>");
return false;
}
else
{
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
});
});
function imageIsLoaded(e) {
$("#file").css("color","green");
$('#image_preview').css("display", "block");
$('#previewing').attr('src', e.target.result);
$('#previewing').attr('width', '250px');
$('#previewing').attr('height', '230px');
};
});
ajax_php_file.php
<?php
if(isset($_FILES["file"]["type"]))
{
$validextensions = array("jpeg", "jpg", "png");
$temporary = explode(".", $_FILES["file"]["name"]);
$file_extension = end($temporary);
if ((($_FILES["file"]["type"] == "image/png") || ($_FILES["file"]["type"] == "image/jpg") || ($_FILES["file"]["type"] == "image/jpeg")
) && ($_FILES["file"]["size"] < 100000)//Approx. 100kb files can be uploaded.
&& in_array($file_extension, $validextensions)) {
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br/><br/>";
}
else
{
if (file_exists("upload/" . $_FILES["file"]["name"])) {
echo $_FILES["file"]["name"] . " <span id='invalid'><b>already exists.</b></span> ";
}
else
{
$sourcePath = $_FILES['file']['tmp_name']; // Storing source path of the file in a variable
$targetPath = "upload/".$_FILES['file']['name']; // Target path where file is to be stored
move_uploaded_file($sourcePath,$targetPath) ; // Moving Uploaded file
echo "<span id='success'>Image Uploaded Successfully...!!</span><br/>";
echo "<br/><b>File Name:</b> " . $_FILES["file"]["name"] . "<br>";
echo "<b>Type:</b> " . $_FILES["file"]["type"] . "<br>";
echo "<b>Size:</b> " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "<b>Temp file:</b> " . $_FILES["file"]["tmp_name"] . "<br>";
}
}
}
else
{
echo "<span id='invalid'>***Invalid file Size or Type***<span>";
}
}
firstly pass a property in ajax
dataType: "JSON"
next you have to build and array of all the data that your out putting in stead of echo for eg
echo "<span id='invalid'>***Invalid file Size or Type***<span>";
change to
$respons['msg']="<span id='invalid'>***Invalid file Size or Type***<span>";
then use
echo json_encode($respons);
this will pass a json object your client side
once there you can console output your data to see how to access the nested objects

Return error from php to dropzone.js

I would like to return an error on a case from my php code that handles the upload.
Currently if the php upload fails the JS still thinks it successes which I presume is to do with the fact it returned fine.
I have tried returning false instead of a string but that still runs the this.on('success') function.
PHP
public function imageUpload(){
//Сheck that we have a file
if((!empty($_FILES["file"])) && ($_FILES['file']['error'] == 0)) {
//Check if the file is JPEG image and it's size is less than 350Kb
$filename = basename($_FILES['file']['name']);
$ext = substr($filename, strrpos($filename, '.') + 1);
if (($ext == "jpg") && ($_FILES["file"]["type"] == "image/jpeg") &&
($_FILES["file"]["size"] < 3500000)) {
//Determine the path to which we want to save this file
$newname = '/home/anglicvw/public_html/newdev/app/templates/default/images/testimages/'.$filename;
//Check if the file with the same name is already exists on the server
if (!file_exists($newname)) {
//Attempt to move the uploaded file to it's new place
if ((move_uploaded_file($_FILES['file']['tmp_name'],$newname))) {
echo "It's done! The file has been saved as: ".$newname;
} else {
echo "Error: A problem occurred during file upload!";
}
} else {
echo "Error: File ".$_FILES["file"]["name"]." already exists";
}
} else {
echo "Error: Only .jpg images under 350Kb are accepted for upload";
}
} else {
echo "Error: No file uploaded";
}
}
JS
$(document).ready(function(){
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone('div#imagesdropzone', { url: '/admin/imageUpload',
parallelUploads: 100,
maxFiles: 100,});
});
Dropzone.options.imagesdropzone = {
init: function() {
this.on('success', function( file, resp ){
console.log( file );
console.log( resp );
});
this.on('error', function( e ){
console.log('erors and stuff');
console.log( e );
});
}
};
Yes, its right. You have to set an HTTP Header.
Have a look at:
https://github.com/enyo/dropzone/wiki/FAQ#how-to-show-an-error-returned-by-the-server
If you have an HTTP Error and want to show it in the hover error message of DropzoneJS you can:
myDropzone.on("error", function(file, message, xhr) {
var header = xhr.status+": "+xhr.statusText;
$(file.previewElement).find('.dz-error-message').text(header);
});
(You need jQuery for that code [$().find();])
The other way would be to return a JSON error message via PHP:
//define text for error message
$output['error'] = 'No Token';
//return right HTTP code
if( $error ){
http_response_code (401);
}
else{
http_response_code (200);
}
//set Content-Type to JSON
header( 'Content-Type: application/json; charset=utf-8' );
//echo error message as JSON
echo json_encode( $output );
Where does this.on('success') take the information about the success/failure of the (internal) PHP upload process?
I guess from the HTTP header's status code, which is 200 (OK) even if the upload failed (it just prints some error text).
I recommend you to set a 500 header if the upload fails.
Use below php code snippet
public function imageUpload(){
//Сheck that we have a file
if((!empty($_FILES["file"])) && ($_FILES['file']['error'] == 0)) {
//Check if the file is JPEG image and it's size is less than 350Kb
$filename = basename($_FILES['file']['name']);
$ext = substr($filename, strrpos($filename, '.') + 1);
if (($ext == "jpg") && ($_FILES["file"]["type"] == "image/jpeg") &&
($_FILES["file"]["size"] < 3500000)) {
//Determine the path to which we want to save this file
$newname = '/home/anglicvw/public_html/newdev/app/templates/default/images/testimages/'.$filename;
//Check if the file with the same name is already exists on the server
if (!file_exists($newname)) {
//Attempt to move the uploaded file to it's new place
if ((move_uploaded_file($_FILES['file']['tmp_name'],$newname))) {
echo "It's done! The file has been saved as: ".$newname;
} else {
header('Error: A problem occurred during file upload!', true, 500);
//echo "Error: A problem occurred during file upload!";
}
} else {
header("Error: File ".$_FILES["file"]["name"]." already exists", true, 500);
//echo "Error: File ".$_FILES["file"]["name"]." already exists";
}
} else {
header("Error: Only .jpg images under 350Kb are accepted for upload", true, 500);
//echo "Error: Only .jpg images under 350Kb are accepted for upload";
}
} else {
header("Error: No file uploaded", true, 500);
//echo "Error: No file uploaded";
}
}

FILE["file1"] is not set through AJAX

I'm new to file uploads, I'm not quite sure what is wrong. Every time I try to upload a file, the server responds saying "File not Uploaded" since $_FILE["file1"] is not set. It is the same with $_FILES["file1"]["tmp_name"] for getimagesize(). I have a gut feeling there is a problem with my AJAX request.
PHP INI FILE has file_uploads = On
My file is within the max file upload size boundaries
I was using a .jpg file for testing.
PHP FILE UPLOAD CODE:
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["file1"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file, PATHINFO_EXTENSION);
// Check if image file is a actual image or fake image
if(!isset($_FILES["file1"])){ //File is always not set ?
echo "File not Uploaded";
die();
}
$check = getimagesize($_FILES["file1"]["tmp_name"]);
if ($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "File is not an image.".$_FILES["file1"]["error"];
$uploadOk = 0;
die();
}
// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
die();
}
// Check file size
if ($_FILES["file1"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
die();
}
// Allow certain file formats
if ($imageFileType !== "jpg" && $imageFileType !== "png" && $imageFileType !== "jpeg" && $imageFileType !== "gif") {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
die();
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
die();
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["file1"]["tmp_name"], $target_file)) {
echo "The file " . basename($_FILES["file1"]["name"]) . " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
AJAX UPLOAD SCRIPT:
function _(str) {
return document.getElementById(str);
}
function uploadFile() {
var formData = new FormData($('form')[0]);
alert(formData);
$.ajax({
url: 'file.php', //Server script to process data
type: 'POST',
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false,
xhr: function () { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { // Check if upload property exists
myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
success: function (data) {
_("filename").innerHTML = data;
},
});
function progressHandlingFunction(e) {
if (e.lengthComputable) {
$('progress').attr({value: e.loaded / e.total, max: e.total});
}
}
}
HTML DOC:
<form action='/' method='post' enctype="multipart/form-data">
<input type="button" onclick="document.getElementById('file1').click();
return false;" value="Upload File" class="btn btn-primary">
<span id="filename" class="label label-success"></span>
<input type="file" id="file1" name="file1" style="visibility: hidden" onchange="filenameprint()">
<input type="button" onclick="uploadFile()" value="Upload File">
<script>
function filenameprint() {
var file1 = document.getElementById('file1').value;
if (!empty(file1)) {
document.getElementById('filename').innerHTML = file1;
} else {
document.getElementById('filename').innerHTML = "No File Chosen"
}
}
</script>
<progress value="0" max="100"></progress>
</form>
I think you are sending the wrong formData. You should just send the file.
var fileInput = $('#file1');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('file', file);

Categories

Resources