Uploading base64 pdf - javascript

I am making a file manager. Now I ran into the problem while trying to upload pdf files. The code I have so far that uploads images is working fine.
When i convert the pdf to a base64 string and open it in an tab, it shows the correct file and is working.
When I upload the file it uploads correctly, however when i open the uploaded file it seems to be corrupted.
Piece of code for uploading files i have:
JavaScript:
if(files[0].type.match(/\/pdf$/)){
var reader = new FileReader();
reader.readAsDataURL(files[0]);
reader.onload = function () {
uploadFile(reader.result, 'pdf', 'pdf', files[0].name);
console.log(reader.result); //shows correct base64
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
function uploadFile(file, name, type, file_name) {
var file_name = file_name.split('.')[0];
var $row = renderFileUploadRow(file_name, name);
$('body').append($row);
var fd = new FormData();
fd.append('file_data', file);
fd.append('do', 'upload');
fd.append('type', type);
fd.append('name', name)
fd.append('file_name', file_name);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'control.php?');
xhr.onload = function(data) {
$row.remove();
};
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
$row.find('.progress').css('width', (e.loaded / e.total * 100 | 0) + '%');
}
};
xhr.send(fd);
}
PHP receiving the ajax call:
if ($_POST['do'] == 'upload') {
$type = $_POST['type'];
$img = $_POST['file_data'];
$img = str_replace('data:image/'.$type.';base64,', '', $img);
echo "$type";
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
if ($type == 'jpeg') {
$type = 'jpg';
}
define('UPLOAD_DIR', 'data/'.$_POST['name'].'/');
$upload = UPLOAD_DIR . $_POST['file_name'] . '.'.$type;
if (file_exists($upload)==1){
$nummer = '1';
while(file_exists(UPLOAD_DIR . $_POST['file_name'] .'('. $nummer . ').'.$type)) {
$nummer++;
}
$upload = UPLOAD_DIR . $_POST['file_name'] .'('. $nummer .').'.$type;
}
$success = file_put_contents($upload, $data);
exit;
}
I expected to upload correctly because when i made images first and tested it, the files were uploaded correct. Now it uploads but the file is corrupted.
What am i doing wrong here?

Related

How to store or upload audio file in specific location?

I need to store recorded voices at one specific location. How to store or upload recorded file to location?
Here is my script for upload audio file & upload.php file
This is my reference link: https://blog.addpipe.com/using-recorder-js-to-capture-wav-audio-in-your-html5-web-site/
//upload link
var upload = document.createElement('a');
upload.href="#";
upload.innerHTML = "Upload";
upload.addEventListener("click", function(event){
var xhr=new XMLHttpRequest();
xhr.onload=function(e) {
if(this.readyState === 4) {
console.log("Server returned: ",e.target.responseText);
}
};
var fd=new FormData();
fd.append("audio_data",blob, filename);
xhr.open("POST","upload.php",true);
xhr.send(fd);
})
li.appendChild(document.createTextNode (" "))//add a space in between
li.appendChild(upload)//add the upload link to li
upload.php
<?php
print_r($_FILES); //this will print out the received name, temp name, type, size, etc.
$size = $_FILES['audio_data']['size'];
$input = $_FILES['audio_data']['tmp_name'];
$output = $_FILES['audio_data']['name'].".wav";
move_uploaded_file($input, $output)
?>
target_dir=>where don you want to store it
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["audio_data"]["name"]);
if (move_uploaded_file($_FILES["audio_data"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["audio_data"]["name"]). " has been
uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}

File is corrupted after converting

I am using recorder.js library and want to send the recorded message to my gmail account using PHPMailer. I have done everything but the only problem that I am getting is that when I send the file as an attachment and download it from my mail, it is corrupted (or whatever) and my system says "The file is unplayable". Moreover, when I check my local uploads/ folder where I am writing all the files, they are unplayable too. I don't know what seems to be the problem and I am stuck on this since past two days. Thanks in advance.
My JS call to upload.php
function sendMessage() {
var xhr = new XMLHttpRequest();
xhr.onload = function (e) {
if (this.readyState === 4) {
console.log("Server returned: ", e.target.responseText);
}
};
var fd = new FormData();
fd.append("audio_data", blob, filename);
xhr.open("POST", "upload.php", true);
xhr.send(fd);
}
and my upload.php
<?php
require "php-mailer-master/PHPMailerAutoload.php";
define('UPLOAD_DIR', 'uploads/');
$a = $_FILES['audio_data']['name'];
$a = str_replace('data:audio/wav;base64,', '', $a);
$a = str_replace(' ', '+', $a);
$data = base64_decode($a);
$file = UPLOAD_DIR . uniqid() . '.wav';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
Please note that I have skipped the part of code which is actually sending mail because I believe that is irrelevant.

jQuery - Append file name to FormData and get it in a PHP script

I have the following JS code that I use to upload an image based on its path:
var data = new FormData();
data.append('fileName', fileName);
data.append('file', file);
$.ajax({
url : dbPath + "upload-file.php",
type: 'POST',
data: data,
contentType: false,
processData: false,
mimeType: "multipart/form-data",
success: function(data) {
Swal.close();
var fileURL = dbPath + data;
console.log('FILE UPLOADED TO: ' + fileURL);
This is my upload-image.php script:
<?php
$fileName = $_POST['fileName'];
if ($_FILES["file"]["error"] > 0) {
echo "Error: " .$_FILES["file"]["error"]. "<br>";
} else {
// Check file size
if ($_FILES["file"]["size"] > 20485760) { // 20 MB
echo "Sorry, your file is larger than 20 MB. Upload a smaller one.";
} else { uploadImage(); }
}// ./ If
// UPLOAD IMAGE ------------------------------------------
function uploadImage() {
// generate a unique random string
$randomStr = generateRandomString();
$filePath = "uploads/".$randomStr."".$fileName;
// upload image into the 'uploads' folder
move_uploaded_file($_FILES['file']['tmp_name'], $filePath);
// echo the link of the uploaded image
echo $filePath;
}
// GENERATE A RANDOM STRING ---------------------------------------
function generateRandomString() {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i<20; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
?>
Everything works fine in a matter of uploading a file, a JPG image for example, but my purpose is to use:
data.append('fileName', fileName);
to simply append the file name and extension to my FormData and get a file URL like this:
https://example.com/_json/uploads/03aC8qsIk4hanngqO3G4_fileName.jpg
But the $fileName variable in my PHP script fires an error_log line as Undefined index fileName in line xx, so is there a way to upload a file, get its name and extension and append it to the file URL that my PHP script generates?
I hope my question is clear, what I'm trying to do is simply a general Ajax automatic upload for any kind of file, not just images, and get their URL based on a random string + its name and extension (like .png, .mp4, .pdf, etc.).
I've figured it out, thanks to all the comments, I had to append the fileName to my FormData() and edit my PHP script as it follows:
JS:
function uploadFile() {
var dbPath = '<?php echo $DATABASE_PATH ?>';
var file = $("#file")[0].files[0];
var fileName = file.name;
console.log('FILE NAME: ' + fileName);
Swal.fire({icon: 'success', title: 'Loading...', showConfirmButton: false })
var data = new FormData();
data.append('file', file);
data.append('fileName', fileName); <!-- ADDED THIS LINE
$.ajax({
url : dbPath + "upload-file.php?fileName=" + fileName, <!-- ADDED THIS LINE
type: 'POST',
data: data,
contentType: false,
processData: false,
mimeType: "multipart/form-data", <!-- ADDED THIS LINE
success: function(data) {
Swal.close();
var fileURL = dbPath + data;
console.log('FILE UPLOADED TO: ' + fileURL);
// error
if (data.includes("ERROR:")) {
Swal.fire({ icon: 'error', title: 'Oops...', text: data, });
// show file data
} else {
$("#fileURL").val(fileURL);
$("#viewButton").attr("href", fileURL);
$("#viewButton").css("display", "block");
}
// error
}, error: function(e) {
Swal.fire({ icon: 'error', title: 'Oops...', text: 'Something went wrong: ' + e.message, });
}});
}
My upload-file.php script:
<?php include 'config.php';
if ($_FILES["file"]["error"] > 0) {
echo "Error: " .$_FILES["file"]["error"]. "<br>";
} else {
// Check file size
if ($_FILES["file"]["size"] > 20485760) { // 20 MB
echo "ERROR: Your file is larger than 20 MB. Please upload a smaller one.";
} else { uploadImage(); }
}// ./ If
// UPLOAD IMAGE ------------------------------------------
function uploadImage() {
// generate a unique random string
$randomStr = generateRandomString();
$filePath = "uploads/".$randomStr;
// upload image into the 'uploads' folder
move_uploaded_file($_FILES['file']['tmp_name'], $filePath);
// echo the link of the uploaded image
echo $filePath;
}
// GENERATE A RANDOM STRING ---------------------------------------
function generateRandomString() {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i<20; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString."_".$_POST['fileName']; <!-- ADDED THIS LINE
}
?>
Now I can finally upload any type of file and get its name + extension at the end of the URL, it works perfectly.

Store Canvas image filename and/or location path to database whilst saving?

I have a canvas image on my page with a Save button that saves down a PNG image file.
function save() {
var canvas = document.getElementById('drawing');
var dataURL = canvas.toDataURL();
$.ajax({
type: "POST",
url: "canvas_ajax_upload_post.php",
data: { img: dataURL }
}).done(function(msg){
alert(msg);
});
}
The canvas_ajax_upload_post.php looks like this:
<?php
$img = $_POST['img'];
if (strpos($img, 'data:image/png;base64') === 0) {
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = 'uploads/img'.date("YmdHis").'.png';
if (file_put_contents($file, $data)) {
echo "The canvas was saved as $file.";
} else {
echo 'The canvas could not be saved.';
}
}
?>
This works fine, images get saved to the uploads folder on my server. What I have been trying to do is store the filename in my SQL database. I have a hidden form field on my main page that I would like to pass the filename or filepath to after the image has been saved, but I cannot figure out how.
I have tried embedding JavaScript code in the PHP file, but it just treats it as a text string and includes it in the alert popup. Essentially what I am trying to do is use the $file variable from the php file in JavaScript code.
E.g. document.getElementById("hidden_form_field").value = $file;
Can anybody help?
You can pass the filename in the data object:
function save() {
var canvas = document.getElementById('drawing');
var dataURL = canvas.toDataURL();
$.ajax({
type: "POST",
url: "canvas_ajax_upload_post.php",
data: {
img: dataURL,
filename: document.getElementById("hidden_form_field").value
}
}).done(function(msg){
alert(msg);
});
}
Then retrieve the "filename" variable by getting $_POST["filename"]:
<?php
$img = $_POST['img'];
$filename = $_POST['filename'];
if (strpos($img, 'data:image/png;base64') === 0) {
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = 'uploads/img'.date("YmdHis").'.png';
if (file_put_contents($file, $data)) {
echo "The canvas was saved as $file.";
} else {
echo 'The canvas could not be saved.';
}
// DO SOME SQL QUERY W/ $filename variable
// SQL CODE HERE
}
?>
You'll need include your SQL query code to use the $filename variable. I didn't see that code in your question.
By what I understand from your question, you're trying to get the value of $file back form php.
You can return the value via the msg variable (which is what php echos) in your $.ajax.done function.
For example:
function(msg){
alert(msg);
if(msg.search("The canvas was saved as")!=-1){//was saved
document.getElementById("hidden_field").value=msg.slice(23);//assuming string "The canvas was saved as $file."
}
}

Combine $_FILES and $_POST into one AJAX call with Javascript only

I am having difficulty sending an ajax call that contains both a file and a string. I have no difficulty making either post or file, but not both together. I need this in pure Javascript, which i am more proficient than Jquery.
here is the code i am working with...
function uploadFile(){
var title = _('title').value;
var genere = _('genere').value;
var stars = _('stars').value;
var description = _('description').value;
var file = _("video").files[0];
//alert(file.name+" | "+file.size+" | "+file.type);
var formdata = new FormData();
formdata.append("video", file);
formdata.append("title", title);
formdata.append("genere", genere);
formdata.append("stars", stars);
formdata.append("description", description);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "video_php/video_upload.php");
ajax.send(formdata);
}
function progressHandler(event){
var percent = (event.loaded / event.total) * 100;
_("progressBar").value = Math.round(percent);
_("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
_("status").innerHTML = event.target.responseText;
_("progressBar").value = 0;
}
function errorHandler(event){
_("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
_("status").innerHTML = "Upload Aborted";
}
This is the php.....
<?PHP
$fileName = '';
$fileTmpLoc = '';
$fileType = '';
$fileSize = '';
$title = '';
$genere = '';
$stars = '';
$description = '';
$retn= '';
if (!isset($_FILES["video"]["name"])) { // if file not chosen
echo "ERROR: Please browse for a file before clicking the upload button.";
exit();
}else{
$fileName = $_FILES["video"]["name"]; // The file name
$fileTmpLoc = $_FILES["video"]["tmp_name"]; // File in the PHP tmp folder
$fileType = explode('.',$fileName); // The type of file it is
$fileType = end($fileType); // The end type of file it is
$fileSize = $_FILES["video"]["size"]; // File size in bytes
$title = preg_replace('#[^a-z0-9, ]#i', '', $_POST['title']);
$genere = preg_replace('#[^a-z0-9, ]#i', '', $_POST['genere']);
$stars = preg_replace('#[^a-z0-9, ]#i', '', $_POST['stars']);
$description = preg_replace('#[^a-z0-9, ]#i', '', $_POST['description']);
}
echo $fileName.'<br/>';
echo $fileTmpLoc.'<br/>';
echo $fileType.'<br/>';
echo $fileSize.'<br/>';
echo $title.'<br/>';
echo $genere.'<br/>';
echo $description.'<br/>';
?>
I have been stuck on this for weeks. I have been through SO as well as many other sites with google. Every answer CLOSE to my desired result has been in Jquery. One solution i had was to make a 2-step form, uploading first one dataset, then the other, but i think both can be sent together for user usability. I have seen it done on several other websites.
NOTE*
Above code has been corrected. Added
formdata.append("video", file);
formdata.append("title", title);
formdata.append("genere", genere);
formdata.append("stars", stars);
formdata.append("description", description);
It is now fully functional, thanks to #Ohgodwhy
Origional Question is at Send $_POST and $_FILE data to php with JAVASCRIPT
Looks like you want the value of _('title') to be added to the formdata.
Given that you have this:
formdata.append("video", file);
All you need to do is this:
formdata.append('title', title);
The FormData object will handle the transmission of the file, and title will be available as $_POST['title'];

Categories