I am trying to send an audio blob over to my Rails action through an ajax POST. I seem to get over to the Rails action but the data I am sending appears to be empty and my audio file is not saved. I can do this with simple javascript, but I cannot seem to get this to work with ajax.
Ajax not working:
function sendRecToPostAjax(blob){
var data = new FormData();
data.append("audio", blob, (callid + ".oga"));
data.append('callid', callid);
return $.ajax({
url: '/controller/action',
type: 'POST',
cache: false,
data: data,
processData: false,
contentType: false
});
}
JS working:
function sendRecToPost(blob) {
var data = new FormData();
data.append("audio", blob, (callid + ".oga"));
data.append('callid', callid);
var oReq = new XMLHttpRequest();
oReq.open("POST", "/controller/action");
oReq.send(data);
oReq.onload = function(oEvent) {
if (oReq.status == 200) {
console.log("Uploaded");
} else {
console.log("Error " + oReq.status + " occurred uploading your file.");
}
};
}
Related
I'm learning programing, could you explain me how to call a service using ajax javascript?
Service information:
Service type: REST
Basic authentication
Estructure: Application/JSON
Url: https://osb.urosario.edu.co/uxxi-URO/WsFotografias/proxy/AdministradorFotografiasJsonPS/fotos/consultar
User: Admi
Password: admi
Parameter JSON example: {"identificacion":["98122811999"]}
I've tested this service in postman
Service answer:
{
"respuesta": [
{
"estado": "Correcto.",
"identificacion": "98122811999",
"imagen": "return string Base 64 format"
}
]
}
Using JQuery :
$.ajax({
type: 'POST',
url: 'https://osb.urosario.edu.co/uxxi-URO/WsFotografias/proxy/AdministradorFotografiasJsonPS/fotos/consultar',
dataType: 'json',
data:{"identificacion":["98122811999"]}
contentType: "application/json"
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', make_base_auth("admi", "admi"));
},
success: function (data,status) {
//do what you want with the data after success
//in this example the response will be promoted in the browser console
console.log(data);
});
});
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return 'Basic ' + hash;
}
You can call your above RestEndpoint using below:
xmlhttp.open("POST", "/EndpointURI", true);
xmlhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
//Use parse() method to convert JSON string to JSON object
var responseJsonObj = JSON.parse(this.responseText);
//use response
}
};
var jsonData = {"name" : "yourData"};
xmlhttp.send( JSON.stringify( jsonData ) );
For Authentication use this:
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://EndPointURI", true);
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", 'Basic ' + btoa('userName:password'));
xhr.onload = function () {
console.log(xhr.responseText);
};
xhr.send();
For authentication part, use JQuery then it will easy for the implementation and as well for understanding. as now aday no body use basic xmlhttp for calling api in javascript, last time i used was a 2003 developed application.
I have two blob file that recived from two recording method
window.recorderr = new MediaRecorder(stream, {
type:'video/mp4'
});
recorderr.start(99999999999999999);
window.recorder = new MediaRecorder(stream, {
type: 'video/mp4'
});
recorder.start(99999999999999999);
};
And i tried to save the file on a stop button click like this calling two events in a single click
btnStopRecording.onclick = function () {
stoprecordinguserstream();
stoprecordinglocalstream();
};
function stoprecordinguserstream()
{
if (!window.recorder) return;
recorder.ondataavailable = function (event) {
var blob = event.data;
var video = document.getElementById('recordedvideo');
video.src = URL.createObjectURL(event.data);
var formData = new FormData();
formData.append("MethodName", "saveuser");
formData.append("data", event.data);
$.ajax({
type: 'POST',
url: '/RecordSve.ashx',
data: formData,
processData: false,
contentType: false,
})
.done(function (data) {
console.log(data);
recordedsource = data;
});
console.log(blob.size, blob);
};
recorder.stop();
}
function stoprecordinglocalstream()
{
if (!window.recorderr) return;
recorder.ondataavailable = function (event) {
var blob = event.data;
var video = document.getElementById('recordedvideolocal');
video.src = URL.createObjectURL(event.data);
var formData = new FormData();
formData.append("MethodName", "saveclient");
formData.append("data", event.data);
$.ajax({
type: 'POST',
url: '/RecordSve.ashx',
data: formData,
processData: false,
contentType: false,
})
.done(function (data) {
console.log(data);
recordedsource = data;
});
console.log(blob.size, blob);
};
recorderr.stop();
}
but the above method only saving one file at a time how can i save two files in a single button click?
my handler function goes like this
public void ProcessRequest(HttpContext context)
{
MethodName = context.Request.Params["MethodName"];
switch (MethodName)
{
case"saveuser":
saveuservideo(context);
break;
case"saveclient":
saveclientvideo(context);
break;
default:
break;
}
}
The purpose of this is Iam trying to save video that recorded from a live session chat since i couldn't find any better way for saving it i tried to save it as two file as it is and merging the two files for a final output but Iam struggling to save multiple files at a time any help would be apreciated.
Here is how i over come the situvation using $.when()
$.when(stoprecordinguserstream(), stoprecordinglocalstream()).then(console.log('sucess'));
I'm making a POST with AJAX and trying to test the data that gets sent, but I'm getting the error "paramString.split is not a function" when that test runs. I've looked for other posts about this but they all seem to be about getting FormData to work with AJAX, which I'm not having trouble with. The data sends, but I can't write a successful test around it.
AJAX:
upload: (file, progressCallback) => {
let data = new FormData();
data.append('image', file);
return $.ajax({
xhr: function() {
let xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', progressCallback);
return xhr;
},
method: 'POST',
url: apiUrl(),
cache: false,
processData: false,
contentType: false,
data: data
});
}
Test:
describe('my test', () => {
beforeEach(function() {
jasmine.Ajax.install()
});
afterEach(function() {
jasmine.Ajax.uninstall();
});
it('sends a POST request to the right endpoint with data', function() {
const image = {
size: 10000,
type: 'image/jpeg'
};
let data = new FormData();
data.append('image', image);
myService.upload(image); // POST happens here
const request = jasmine.Ajax.requests.mostRecent();
expect(request.method).toBe('POST'); // passes
expect(request.url).toBe('/dashapi/dam-assets/'); // passes
expect(request.data()).toEqual(data); // error
});
Error
TypeError: paramString.split is not a function
The error is occurring at this line:
https://github.com/jasmine/jasmine-ajax/blob/master/src/paramParser.js#L18. I put a breakpoint there and paramString is actually a FormData object at that point. I'm assuming that mocking out the request with jasmine.Ajax.install is overwriting the processData: false I have in the original request, but I'm not sure how to fix that.
I had to change the test to be
expect(request.params).toEqual(data);
Could anyone help me?
I'm trying to write a script that when the user clicks an image, that this triggers an image in the database to be updated.
For this I wrote the code which temporarily makes the Caller Line of the method in the controller, but when I send the form it is not validated because of Cross-Site-Request-Forgery.
$("#upload_picture").on('click', function (e) {
e.preventDefault();
$("#bundle_user_file").trigger('click');
});
$("#bundle_user_file").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('.active-img').attr('src', e.target.result);
};
reader.readAsDataURL(this.files[0]);
ajax_formData()
}
});
This is my Caller Line ajax, is do the treatment in the form with the FormData to post, caught the routes and the token. He calls route, but not sure if the image is going or not, even with the Inspector firefox.
function ajax_formData() {
var at = $("form[name=bundle_user]");
var formData = new FormData();
formData.append('file', $("input[type=file]")[0].files[0]);
var url = at.attr('action') + '?_token=' + $("#bundle_user__token").val();
$.ajax({
type: "PUT",
url: url,
data: formData,
success: function (data) {
alert("success: " + data.message);
},
fail: function (data) {
alert("error: " + data.message);
},
cache: false,
contentType: false,
processData: false,
xhr: function () { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { // Avalia se tem suporte a propriedade upload
myXhr.upload.addEventListener('progress', function () {
/* faz alguma coisa durante o progresso do upload */
}, false);
}
return myXhr;
}
});
}
This is the method in controlodor it with a common call with the click the button to submit change my image. But as I said before the ajax call, he replied that the Token not available
public function updateAction(Request $request, $id)
{
$this->denyAccessUnlessGranted('ROLE_USER', null, 'Unable to access this page!');
$em = $this->getDoctrine()->getManager();
$entity = $this->getUser();
if ($entity->getId() != $id) {
$response = new JsonResponse(
array(
'message' => 'Não tem permissao'
), 400);
return $response;
}
$form_update = $this->updateForm($entity);
$form_update->handleRequest($request);
if ($form_update->isValid()) {
$entity->upload();
$em->persist($entity);
$em->flush();
return new JsonResponse(array('message' => 'Success!'), 200);
}
$response = new JsonResponse(
array(
'message' => $form_update->getErrors()
), 400);
return $response;
}
Firstly, I notice that your click event for #upload_image fires a click trigger on #bundle_user_file, but below that you are asking it to look for a change event. Therefore, this would do nothing.
You can re-generate a CSRF token if you want by calling the csrf token_manager service by doing this:
/** #var \Symfony\Component\Security\Csrf\CsrfTokenManagerInterface $csrf */
$csrf = $this->get('security.csrf.token_manager');
$token = $csrf->refreshToken($tokenId);
return new Response($token);
You can determine $tokenId in your form, if you want, or just use your picture ID, or whatever. Normally the CSRF token is generated automatically from your session, so you might want to check that too.
function upload_img(){
var file_data = $('.myform').find('.drawing').prop("files")[0];
var form_data = new FormData();
form_data.append("drawing", file_data);
$.ajax({
url: "upload.php",
type: "POST",
data: form_data,
contentType: false,
dataType:'json',
cache: false,
processData:false,
success: function(data)
{
},
error: function()
{
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class='myform'>
<input type='file' class='drawing' onchange='upload_img()' >
</form>
I need to read data from FormData? I try to read something like someFormatData["valueName"] but it not working.
options["fileId"] or options["file"] does not work. Also I try options.fileId same result:
function upload(file, fileId, callback) {
var formData = new FormData();
formData.append("file", file);
formData.append("fileID", fileId);
$.ajax({
url: '/url',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
callback(response);
}
});
}
asyncTest("test upload chunk", function() {
var blob = new Blob(["Hello world!"], { type: "text/plain" }),
options = null,
fileID ="someFileID",
response;
jQuery.ajax = function(param) {
options = param; // THIS is FormData object
// how to read fileId and file from here
};
upload(blob, fileID, function (data) {
response = data;
});
options.success({
someProp: 'responseFromServer'
});
setTimeout(function() {
QUnit.equal(options, "dataTosend", "parameters is OK");
QUnit.equal(response["someProp"], "responseFromServer", "Response ok");
start();
},1000);
});
If you take your FormData object you can use a few different methods on it… What you are looking for is
formData.get()
or
formData.getAll()
https://developer.mozilla.org/en-US/docs/Web/API/FormData
Note that the get() method is not fully supported on all browsers.
You can read using this
formData.get('fileId') // to read Id
formData.get('file') // to read the file
Another way to list all entries of a FormData :
for(const entry of formData){
console.log(entry); // Array: ['entryName', 'entryValue']
}