Store Audio from Blob url to server in Laravel - javascript

I've a portal in which I'm recording user audio and I am getting a blob URL and now I want to store this blob url as a file in my database. Can anyone help me with this.
This is my js code
$('#upload-read-aloud').on('submit',function(e){
e.preventDefault();
$.ajax({
type : 'GET',
cache : false,
data : {audioUrl:audioUrl},
url : '../upload-read-aloud-test',
success:function(response){
alert(response)
}
})
})
And this is my controller code
$url = $req->audioUrl;
$upload_dir = public_path()."/assets/";
$audio= $url;
$audio= str_replace('data:audio/wav;base64,', '', $audio);
$audio = str_replace(' ', '+', $audio);
$data = base64_decode($audio);
$file = $upload_dir . time() . ".wav";
$success = file_put_contents($file, $data);
echo $success ? $file : 'Unable to save the file.';
audioUrl is the Blob url which I'm passing in my route. The file is saving into the database but the file is empty.

As I see you use jQuery.
So, first of all DO NOT use GET request to upload data to server, use POST request instead. And send your blob as a file. Look at - https://stackoverflow.com/a/34340245/2585154
var s = 'some string data';
var filename = 'foobar.txt';
var formData = new FormData();
formData.append('file', new File([new Blob([s])], filename));
formData.append('another-form-field', 'some value');
$.ajax({
url: '/upload',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function () {
console.log('ok');
},
error: function () {
console.log('err'); // replace with proper error handling
}
});
Replace /upload with path to your API method, e.g.: ../upload-read-aloud-test, replace var s = 'some string data'; with your blob data and replace var filename = 'foobar.txt'; with any meaningful filename.
Or if you want to upload file from input, look at - jQuery AJAX file upload PHP
$('#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
}
});
});
Replace upload.php with path to your API method, e.g.: ../upload-read-aloud-test, replace #sortpicture with your input id.
And then access your uploaded file in Laravel:
$file = $req->file('file');
dump($file);

Related

Can't receive files from JQuery Ajax request in Laravel

When trying to upload a file CSV / Excel file and receiving it in an ajax request, it's not working as expected.
I used a formdata object to upload the files like such:
const formData = new FormData()
formData.append('file', file)
//upload the file to the server
Api.makeRequest('uploadFromFile', {
processData: false,
contentType: false,
enctype: 'multipart/form-data',
cache: false,
data: formData,
complete: function (xhr) {
if(xhr.status === 201 || xhr.status === 200){
console.log(xhr.responseJSON)
}else {
alert('error')
console.error(xhr.responseJSON)
}
}
})
As I read from the documentation, you have to extract it like such:
$file = $request ->file('file_key')
When using this syntax, I get an error, and Laravel can't extract the file:
public function uploadFromFile(Request $request){
if($request->hasFile('file')){
$file = $request->file('file');
return $file;
}else{
return response()->json(['error' => 'No file uploaded'], 400);
}
However, it works fine when I use the regular request->has() function. A return type is just an object. What am I doing wrong since I can't get the file in the correct format?
//This works, getting some data but not a proper file object
public function uploadFromFile(Request $request){
if($request->has('file')){
$file = $request->get('file');
return $file;
}else{
return response()->json(['error' => 'No file uploaded'], 400);
}
<script>
var droppedFiles='';
//input file change event to call this function
function FileUpload(e)
{
droppedFiles = e.target.files || e.dataTransfer.files;
}
$('#FrmId').on('submit', function (e) {
var $form = $('#FrmId');
var $input = $form.find('input[type="file"]');
var form_data = new FormData($('#FrmId')[0]);
if (droppedFiles)
{
$.each( droppedFiles, function(i, file) {
form_data.append( $input.attr('name'), file );
});
}
$.ajax({
type: "POST",
enctype: "multipart/form-data",
url: "url",
data: form_data,
contentType: false,
cache: false,
processData: false,
}).done(function (data) {
}).fail(function () {
});
return false;
});
</script>

Problem Sending FormData to PHP together with string data

I want to send the file data together with string data. I am able to send it from ajax to PHP. But in PHP I can not get correct string data from $_POST[] This doesn´t work. I don´t know how to get the correct string.
I got only initial alphabet from a string. No specific product that I want.
Here is ajax
var action = "product1="+myProduct1+"&product2="+product2;
var file_data = $('#myfile').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
form_data.append('action', action);
$.ajax({
type: "POST",
url: "URL TO PHP",
data:form_data,
dataType: 'json',
contentType: false,
processData: false,
success: function(response){
//Do something
},
});
PHP
$data=$_POST['data'];
$action=$_POST['action'];
$mydata = array("myStatus"=>"ok", "myMsg"=>$action['product1']);
echo json_encode($mydata);
UPDATE
I found one solution :
javascript script:
var file_data = $('#myfile').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
form_data.append('product1',my_product1);
form_data.append('product2',my_product2);
PHP code :
$data=$_POST['data'];
$mydata = array("myStatus"=>"ok", "myMsg"=>$_POST['product2']);
echo json_encode($mydata);
I am a bit satisfy with this. If someone has another solution would be nice. Because I have lots of string data in this code. If I do manual like this....will look stupid. Unless this is the only solution I can do.
you may try like this,
var action = [
{
product : "product1",
},
{
product : "product2"
}];
var file_data = $('#myfile').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
form_data.append('action', JSON.stringify(action));
$.ajax({
type: "POST",
url: "URL TO PHP",
data:form_data,
dataType: 'json',
contentType: false,
processData: false,
success: function(response){
//Do something
},
});
and in php side,
$data = json_decode($post,true);
//print_r($data);
foreach ($data as $key => $value) {
echo $value['product'];echo "<br>";
}

Ajax request does not send blob data

I want to send data using an Ajax request to PHP.
I have the following data in my formData variable:
var formData = new FormData();
formData.append('fname', inputFname.value);
formData.append('lname', inputLname.value);
formData.append('email', inputEmail.value);
formData.append('data', newBlob);
Printing the form entries gives me this:
I do the request like this:
$.ajax({
type: 'POST',
url: 'post.php',
data: formData,
crossDomain: true,
processData: false,
contentType: false,
success: function(data) {
console.log("success!")
},
error: function() {
console.log("error!")
}
})
In post.php I print the recieved data:
print_r("First name: " . $_POST["fname"] . PHP_EOL);
print_r("Last name: " . $_POST["lname"] . PHP_EOL);
print_r("Email: " . $_POST["email"] . PHP_EOL);
print_r("Data: " . $_POST["data"] . PHP_EOL);
For some reason it does not receive the 'data' entry in the $_POST variable. I get the following notice: "Notice: Undefined index: data"
Why does that happen? Could I somehow send the blob information?
As requested, the whole code. (inputFname, inputLname and inputEmail are not null. The code is situated inside a button onclick event method.
let evtTgt = e.target;
const container = evtTgt.parentNode;
const audioElement = container.getElementsByTagName("audio")[0];
const audioURL = audioElement.src;
let newBlob = await fetch(audioURL).then(result => result.blob());
var formData = new FormData();
formData.append('fname', inputFname.value);
formData.append('lname', inputLname.value);
formData.append('email', inputEmail.value);
formData.append('data', newBlob);
for (var key of formData.entries()) {
console.log(key[1]);
}
$.ajax({
type: 'POST',
url: 'post.php',
data: formData,
crossDomain: true,
processData: false,
contentType: false,
success: function(data) {
console.log("success!")
},
error: function() {
console.log("error!")
}
})
All this time I was looking for the blob contents inside the $_POST variable. I should have looked in the $_FILES variable instead!
I managed to get the file contents by calling this inside the php script:
$fileinfo = file_get_contents($_FILES['data']['tmp_name']);

Sending a blob image via ajax using django

After a video is processed, I'm passed an instance of a Javascript "Blob" object, which contains the preview image (In JPEG format). I want to send the image via an ajax POST to the backend on django and am having trouble doing so.
I tried to encode to base64 in javascript, and then decode it in python and create the image again, but the image file can't be opened; it's either damaged or corrupt. I included the code that I wrote below:
Django:
def thumbnail_photo(request):
if request.POST:
data = request.POST.get('thumbnail')
convert = base64.b64decode(data)
image_result = open('thumbnail.jpeg', 'wb')
image_result.write(convert)
Javascript:
onPreviewAvailable: function(previewImageBlob) {
blob = previewImageBlob;
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
base64data = reader.result;
base64 = base64data;
base64 = window.btoa(base64);
data = {'thumbnail': base64};
$.ajax({
url: 'thumbnail_photo',
type: 'POST',
data: data,
dataType:'json',
success: function (data) {
}
});
});
}
I also tried the following:
blob = previewImageBlob;
var oReq = new XMLHttpRequest();
oReq.open("POST", thumbnail_photo, true);
oReq.onload = function (
};
oReq.send(blob);
However, the value either came as empty or I would get an error saying that the file couldn't be sent.
I also tried appending the blob to form data:
var formData = new FormData();
formData.append('file', blob);
$.ajax({
url: 'thumbnail_photo',
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(response) {
console.log('works');
$('#result').text(response);
}
});
Any help is appreciated!!

How to encrypt a binary file with HTML5 File API and upload to server

I need to encrypt and upload file to Apache/PHP server with HTML5 FileReader API and CryptoJS
I've done the following succesfully
Read file with FileReader API
Convert file to base64 with readAsDataURL() function
Encrypt it with the following
CryptoJS.AES.encrypt(e.target.result, password);
But I couldn't manage to send it to server as a File object because I already converted it to text object and I can't convert back it to a file. The following is my javascript file and server-side snippet.
app.js
var reader = new FileReader();
// Read file callback!
reader.onload = function (e) {
// Use the CryptoJS library and the AES cypher to encrypt the
// contents of the file, held in e.target.result, with the password
var encrypted = CryptoJS.AES.encrypt(e.target.result, password);
//SEND FORM DATA
var data = new FormData($("#fileinfo")[0]);
/*The following line doesn't work because I'm not adding a File object,
* I'm adding file already converted to Base64 format
*/
data.append('file-0','data:application/octet-stream,' + encrypted);
$.ajax({
url: 'upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (data) {
//alert(data);
}
});
};
upload.php
<?php
var_dump($_FILES); //prints empty array
var_dump($_POST); //prints file as string
?>
I found the answer the new Draft on w3
Here is a working code if anyone need
var reader = new FileReader();
// Read file callback!
reader.onload = function (e) {
var encrypted = CryptoJS.AES.encrypt(e.target.result, password);
var data = new FormData($("#fileinfo")[0]);
var encryptedFile = new File([encrypted], file.name + '.encrypted', {type: "text/plain", lastModified: new Date()});
data.append('file[0]', encryptedFile);
$.ajax({
url: 'upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (data) {
//alert(data);
}
});
};
reader.readAsDataURL(file);

Categories

Resources