javascript / PHP file upload - javascript

I'm using an audio recorder from this place
http://webaudiodemos.appspot.com/AudioRecorder/index.html,
but I instead of saving the file locally I would like to upload it back to the server. My best shot was to try to modify the Recorder.setupDownload function in recording.js script to pass the blob it creates to a simple upload PHP script I found here:
<?php
if(isset($_FILES['image'])){
$errors= array();
$file_name = $_FILES['recording']['name'];
$file_size =$_FILES['recording']['size'];
$file_tmp =$_FILES['recording']['tmp_name'];
$file_type=$_FILES['recording']['type'];
$file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
$extensions = array("wav");
if(in_array($file_ext,$extensions )=== false){
$errors[]="extension not allowed, please choose wav file."
}
if($file_size > 2097152){
$errors[]='File size under 20MB';
}
if(empty($errors)==true){
move_uploaded_file($file_tmp,"images/".$file_name);
echo "Success";
}else{
print_r($errors);
}
}
?>
And I'm tring it using a jquery call,
$.ajax({
type: "POST",
url: "../scripts/Single-File-Upload-With-PHP.php",
data: blob
});
But I'm obviously doing something wrong. The original PHP script has a form in it
used for input, which I commented out trying to call the php code directly.
So my questions would be;
how to modify the Recorder.setupDownload to upload the file to a
designated folder?
how to report back when something goes wrong?
Or alternatively, is there a more elegant solution?
Edit: Regarding what's in the blob
This is how the blob is being defined in recorder.js:
worker.onmessage = function(e){
var blob = e.data;
currCallback(blob);
}
As to my understanding it is created with methods listed in recorderWorker.js (link in comments), and it should contain simply a wav file.

I dont think you should create the blob in the worker, but I had a similar setup (actually based on the same example) where I retrieved the samplebuffers from the worker and save them into the m_data fields of an AudioMixer class that did some stuff to the recording, then:
//! create a wav file as blob
WTS.AudioMixer.prototype.createAudioBlob = function( compress ){
// the m_data fields are simple arrays with the sampledata
var dataview = WTS.AudioMixer.createDataView( this.m_data[ 0 ], this.m_data[ 1 ], this.m_sampleRate );
return( new Blob( [ dataview ], { type:'audio/wav' } ) );
}
WTS.AudioMixer.createDataView = function( buffer1, buffer2, sampleRate ){
var interleaved = WTS.AudioMixer.interleave( buffer1, buffer2 );
// here I create a Wav from the samplebuffers and return a dataview on it
// the encodeWAV is not provided..
return( WTS.AudioMixer.encodeWAV( interleaved, false, sampleRate ) );
}
then to send it to the server
var blob = this.m_projectView.getAudioEditView().getAudioMixer().createAudioBlob();
if( blob ){
//! create formdata (as we don't have an input in a DOM form)
var fd = new FormData();
fd.append( 'data', blob );
//! and post the whole thing #TODO open progress bar
$.ajax({
type: 'POST',
url: WTS.getBaseURI() + 'mixMovie',
data: fd,
processData: false,
contentType: false
} );
}
and I had a node server running where the blob was sent to and could be picked up directly as a wav file, using the express node module:
var express = require( 'express' );
// we use express as app framework
var app = express();
/** mixMovie expects a post with the following parameters:
* #param 'data' the wav file to mux together with the movie
*/
app.post( '/mixMovie', function( request, response ){
var audioFile = request.files.data.path;
....
} );
hope this helps..
Jonathan

In the end this worked nicely for me:
recorder.js:
$.ajax(
{
url: "./scripts/upload.php?id=" + Math.random(),
type: "POST",
data: fd,
processData: false,
contentType: false,
success: function(data){
alert('Your message has been saved. \n Thank you :-)');
}
});
And the upload script itself:
<?php
if(isset($_FILES['data']))
{
echo $_FILES['data']["size"];
echo $_FILES['data']["type"];
echo $_FILES['data']["tmp_name"];
$name = date(YmdHis) . '.wav';
move_uploaded_file($_FILES['data']["tmp_name"],"../DEST_FOLDER/" . $name);
}
?>

Related

Image crop Code in Symfony 3.3 works in localhost well but does not work in live website

So I recently saw a tutorial and created an Image crop and upload feature in website. In my case I have :-
a. Title
b. Description
c. Image
d. Date
Initially I did exactly like in tutorial when file browse is clicked the image would have mounted in Bootstrap 4 modal where there had a feature to crop. The main problem over there was when I clicked on that crop button the ajax used to run and persist all the data into database. Later I changed in JavaScript so that when crop button is clicked the cropped image is displayed and finally the Submit button would saved all data in database. This feature is working well in Localhost, but when I updated in my live website the features seems not to work.
JavaScript Code:
$('.crop_image').click(function(event){
$image_crop.croppie('result', {
type: 'canvas',
size: 'viewport'
}).then(function(response){
$('#uploadimageModal').modal('hide');
$("#previewImg").attr('src', response);
getResponse = response;
});
$('#upload_btn').on('click',function(){
var block = getResponse.split(";");
// Get the content type
var contentType = block[0].split(":")[1];// In this case "image/gif"
// get the real base64 content of the file
var realData = block[1].split(",")[1];// In this case "iVBORw0KGg...."
// Convert to blob
var blob = b64toBlob(realData, contentType);
let formData = new FormData(form);
formData.append('image_path', blob);
$.ajax({
url: "{{ path('app_bundle_route') }}",
type: 'POST',
data: formData,
processData: false,
contentType: false,
headers: {'X-Requested-With':'XMLHttpRequest'},
success: function(data){
$("#previewImg").attr('src', getResponse);
}
});
Controller:
/**
* #Security("is_granted('ROLE_ADMIN')")
* #Route("/form", name="form")
*/
public function indexAction(Request $request) {
$members = new members();
$form = $this->createForm(event::class, $members);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->redirectToRoute('dev');
}
return $this->render('admin/create.html.twig', [
'form' => $form->createView()
]);
}
/**
* #Security("is_granted('ROLE_ADMIN')")
* #Route("/getImage", name="getImage")
* #Method({"POST"})
*/
public function getImageAction(Request $request){
$members = new members();
$form = $this->createForm(event::class, $members);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
if($request->isXmlHttpRequest()){
/** #var Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $request->files->get('image_path');
//$file = $form->get('image_path');
$filename = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getParameter('event_directory'), $filename);
$title = $form['title']->getData();
$description = $form['description']->getData();
$date = $form['date']->getData();
$members->setImagePath($filename);
$members->setTitle($title);
$members->setDescription($description);
$members->setDate($date);
$em = $this->getDoctrine()->getManager();
$em->persist($members);
$em->flush();
$this->addFlash(
'notice', 'Event Added!!'
);
}
}
return new JsonResponse("This is Ajax");
}
I have deleted cache several times but didn't work. The exact code works in Localhost.

Having a bit of trouble with my AJAX POST request to my PHP file

I'm trying to provide data to my MYSQL Database using Ajax, however, for some reason my PHP file is not reading the JSON array that I post to the file. Within the array I also have a file to store an image on my server as well as my database.
Javascript file
$(document).ready(function(){
// Give Data to PHP
// process the form
$('form').submit(function(event) {
// get the form data
// there are many ways to get this data using jQuery (you can use the class or id also)
//formData.append('tax_file', $('input[type=file]')[0].files[0]
var img = $('input[name=img]').prop('files')[0];
var name = img.name,
tmp = img.tmp_name,
size = img.size,
form = $('input[name=form-submit]').val(),
myName = $('input[name=my-name]').val(),
desc = $('input[name=description]').val();
// document.write(name + tmp + size);
var formData = {
'form-submit' : form,
'my-name' : myName,
'description' : desc,
'img' : name,
'tmp_name' : tmp,
'size' : size
};
// document.write(JSON.stringify(formData));
console.log(formData);
// process the form
$.ajax({
url : 'insert-bio.php', // the url where we want to POST
type : 'POST', // define the type of HTTP verb we want to use (POST for our form)
data : formData, // our data object
processData : false,
contentType : false,
dataType : 'json', // what type of data do we expect back from the server
encode : true
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
// here we will handle errors and validation messages
});
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
});
});
My PHP file
include('../db.php');
$conn = new Database();
echo explode(",", $_POST['data']);
if(isset($_POST['form-submit'])){
// text data
$name = strip_tags($_POST['my-name']);
$desc = strip_tags($_POST['description']);
// picture stuff
$file = rand(1000,100000)."-".$_FILES['img']['name'];
$file_loc = $_FILES['img']['tmp_name'];
$file_size = $_FILES['img']['size'];
$file_type = $_FILES['img']['type'];
// folder for profile pic
$folder = "bio-pic/";
// new file size in KB
$new_size = $file_size/1024;
// make file name in lower case
$new_file_name = strtolower($file);
// final pic file
$final_file=str_replace(' ','-',$new_file_name);
// mysql query for form data
if(move_uploaded_file($file_loc,$folder.$final_file)){
$sql="INSERT INTO bio(img, name, description) VALUES('$final_file', '$name', '$desc')";
$conn->query($sql);
}
} else {
echo "Need data";
}
$query = $conn->query("SELECT * FROM bio");
$results=$query->fetchAll(PDO::FETCH_ASSOC);
$parse_bio_json = json_encode($results);
file_put_contents('bio-DATA.json', $parse_bio_json);
echo $parse_bio_json;
The console shows that I have made contact with my PHP file, but it simply has not read any data.
The error on the PHP file:
Notice: Undefined index: data in /Applications/XAMPP/xamppfiles/htdocs/WEBSITE/BIO/insert-bio.php on line 8
Notice: Array to string conversion in /Applications/XAMPP/xamppfiles/htdocs/WEBSITE/BIO/insert-bio.php on line 8 ArrayNeed data[]
I had the same issue back in the day. After doing lots of research I found out that JSON cannot have a property that holds a file value. However, you can follow this example. It worked great for me. Hope it helps :)
$('#upload').on('click', function() {
var file_data = $('#sortpicture').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
alert(form_data);
$.ajax({
url: 'upload.php', // point to server-side PHP script
dataType: 'text', // what to expect back from the PHP script, if anything
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function(php_script_response){
alert(php_script_response); // display response from the PHP script, if any
}
});
});
PHP
<?php
if ( 0 < $_FILES['file']['error'] ) {
echo 'Error: ' . $_FILES['file']['error'] . '<br>';
}
else {
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
}
?>
Credit goes to -> jQuery AJAX file upload PHP

How to save my generated javascript pdf file to my server's filesystem?

I'm using pdfmake to create my pdf and while it allows the user to open the pdf directly or download it to their computer, I'm not sure how I would go about generating the pdf and saving it to my server's file system.
From what I understand, there are plenty of security measures not allowing javascript to save data to file(s), so would sending it to my php backend be the only choice ? and how would i go about doing that ?
Thanks !
(untested)
PHP:
<?
// pull the raw binary data from the POST array
$data = substr($_POST['data'], strpos($_POST['data'], ",") + 1);
// decode it
$decodedData = base64_decode($data);
// print out the raw data,
echo ($decodedData);
$filename = "test.pdf";
// write the data out to the file
$fp = fopen($filename, 'wb');
fwrite($fp, $decodedData);
fclose($fp);
?>
JS:
var docDefinition = {
content: 'This is an sample PDF printed with pdfMake'
};
pdfMake.createPdf(docDefinition).getBuffer(function(buffer) {
var blob = new Blob([buffer]);
var reader = new FileReader();
// this function is triggered once a call to readAsDataURL returns
reader.onload = function(event) {
var fd = new FormData();
fd.append('fname', 'test.pdf');
fd.append('data', event.target.result);
$.ajax({
type: 'POST',
url: 'upload.php', // Change to PHP filename
data: fd,
processData: false,
contentType: false
}).done(function(data) {
// print the output from the upload.php script
console.log(data);
});
};
// trigger the read from the reader...
reader.readAsDataURL(blob);
});
Upload and receive code from How can javascript upload a blob?.

Rewriting into JSON file using JavaScript/jQuery

I used jQuery to read from a json file, but when I try to write it to the same file, it won't work.
Here's the code:
$.getJSON(src,function(data){
var about= data.abouttext;
var mail= data.mail;
var phone = data.phone;
$("#about_ta").val(about);
$("#mail_ta").val(e);
$("#phone_ta").val(mp);
$("#wizard_tabs_edit").show();
$("#mask_edit").show();
$("#edit_save").on("click",function() {
data.abouttext = $("#about_ta").val();
data.mail = $("#mail_ta").val();
data.phone = $("#phone_ta").val();
$.ajax({
url: src,
type: "POST",
data: data,
contentType: "application/json",
success: function(response){
alert("aaa");
}
});
$("#wizard_tabs_edit").hide();
$("#mask_edit").hide();
});
});
src is the path to the file (working at the $.getJSON), and it's giving me the alert "aaa" when AJAX succeeds.
But still, the JSON file remains the same.
The only way is to use php or any other backend coding language that can handle the file manipulation for you. Below is an example if you use php5 so you can have a clue:
<?php
// Specify filename
$filename = 'myJsonFile.json';
// Read data transforming them to an array
$data = json_decode(file_get_contents($filename), true);
// Push to the array a new pair
array_push($data, ['key' => 'value']);
// Open file for writing
$file = fopen($filename, 'w');
// Write data as json
fwrite($file, json_encode($data));
// Close file
fclose($file);
?>

jQuery-File-Upload inconsistently gives file data

jQuery-File-Upload
Upload script:
$('#fileupload').fileupload({
url: 'api/combox_upload.php',
type: 'POST',
dataType: 'json',
dropZone: $dropZone,
singleFileUploads: true,
done: function (e, data) {
attachments = attachments.concat(data.result);
refreshAttachments();
},
add: function(e, data) {
var file = data.files[0];
data.context =
$('<li>',{'class':'file-upload-item'})
.append($('<span>').text(file.name))
.append(
$('<div>',{'class':'progressbar'})
.append($('<div>',{'class':'progress'}))
).appendTo($fileUploads);
data.submit(); // start upload immediately
},
progress: function(e, data) {
var progress = data.loaded / data.total;
data.context.find('.progress').stop().animate({'width':(progress*100)+'%'},100,'linear');
//data.context.find('.progress').css({'width':(progress*100)+'%'});
}
});
In my api/combox_upload.php script I echo json_encode($_FILES) and half the time it comes back blank (I'm watching the XHR request responses in Chrome developer toolbar).
Why is that? How do I fix it so it always submits the file?
Edit: It seems to happen more frequently with larger files.
Could it be an issue with PHP not handling multipart data correctly? I noticed the XHR request comes in immediately, as soon as the file upload begins, but PHP obviously hasn't gotten the whole file yet... so what does it do? Does it block when I try to access the $_FILES object or does it just give me an empty array? Do I have to something special?
Through trial and error I discovered that this problem only occurs with files larger than about 23 MiB. I'm not sure if that's a universal constant or specific to how my server is configured.
Nevertheless, I figured out how to get around this limitation. You need to set singleFileUploads to true and multipart to false, e.g.
$('#fileupload').fileupload({
url: 'api/upload.php',
type: 'POST',
dataType: 'json',
singleFileUploads: true,
multipart: false,
...
And then in your php script you can read in the data like this:
$handle = fopen('php://input', 'r');
$file_data = '';
while(($buffer = fgets($handle, 4096)) !== false) {
$file_data .= $buffer;
}
fclose($handle);
The $_FILES array will still be empty, so you can't get the filename out of there, but it seems to be set in the Content-Disposition header. I wrote a regex to pull it out:
$headers = getallheaders();
$filesize = strlen($file_data);
if(isset($headers['Content-Disposition']) && preg_match('`\bfilename="((?:\\.|[^"])*)"`',$headers['Content-Disposition'], $m)) {
$filename = urldecode($m[1]);
} else {
$filename = 'unknown';
}

Categories