HTML5 File API - Save blob to file with PHP - javascript

I have the following jQuery, which I think should pass a sliced file to PHP:
var blob = f.slice(start, stop);
var formData = new FormData();
formData.append('fileUpload', blob, f.name);
$.ajax({
url: 'save.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(msg){
alert("Success: " + msg);
},
error: function(bla, msg){
alert("Fail: " + msg);
}
});
However, I'm not sure what the PHP should look like to save the blob to a file.
The intention is for the browser to slice the file and then save the output.

Receive it as a file at your server
<?php
//var_dump($_FILES) // check if you received it or not
$blob = $_FILES('fileUpload');
file_put_contents('/path/to/new/file_name', $blob);
?>
You might want to save the file to a tmp location first, then do some checks on it before you move it to a final location (with PHPs rename() function).
Btw: why not just save the BLOB to DB? That is a legitimate way of handling files these days, that's what the BLOB MySQL data type is for after all.
I already asked this and it worked, have a look: send formData appended with blob to server

Due to contentType: false the data is available in $_FILES rather than $_POST. One way to do it, is like so:
<?php
move_uploaded_file(
$_FILES['fileUpload']['tmp_name'],
$_FILES['fileUpload']['name']
);
?>

Related

JQuery ajax POST with FormData doesn't send any values

There seem to be lots of posts about this, but can't find a solution amongst them and I've hit a brick wall. Help, dear Stackers!
I'm writing a bit of code that lets users choose a profile picture, crop it and then save the cropped image on the server. I'm using the Cropper.js library to handle the actual cropping and have established that's working because I can display the crop live with this code:
var imageData = cropper.getCroppedCanvas().toDataURL();
var profileimage = document.getElementById('myProfilePhoto');
profileimage.src = imageData;
Now I want to send the cropped image to the server, and the best method would appear to be create a blob and Ajax that over to a php script to handle it.
cropper.getCroppedCanvas().toBlob(function (blob) {
var formData = new FormData();
formData.append('file', blob);
formData.append('uuid', '{a unique identifier}');
$.ajax({
type: 'POST',
url: '{the php script}',
data: formData,
processData: false,
contentType: false,
success: function (response) {
console.log('Upload success: '+response);
},
error: function () {
console.log('Upload error');
}
});
});
And at this stage I'm just getting my php script to var_dump($_REQUEST) so I can see in the console what the script thinks it's getting. However, the response is just sending back the default $_REQUEST objects like PHPSESSID and no file or uuid input.
What am I doing wrong?
Thanks in advance for any pointers.
If you are sending via post in order to see the request put this code
var formData = new FormData();
formData.append('file', blob);
formData.append('uuid', '{a unique identifier}');
formData.append('_method', 'PATCH'); <---add this and you're good to go
So the answer was annoyingly simple but frustratingly hard to find.
My server had an .htaccess rewrite rule which automatically changed www. addresses to the non-www version, and obviously I'd been dumb enough to include the www. in the URL I was calling, and it seems that's enough to strip off the $_POST data in these circumstances.
So FormData() and blobs are all red herrings here - it's just a redirect that's the cause.

image data response from jquery .ajax into new ajax call?

I'm trying to chain together the ImageOptim API with the OCR.space API.
Both great API's by the way, I highly recommend them! The issue at hand though is that the OCR api does not accept images over 1 mb or 2600x2600 px in the free tier and thus many sources will need to be optimised before being sent.
Im running this jQuery ajax call to ImageOptim from a cordova wrapped html file:
var compress = function(image) {
console.log("starting compress");
$.ajax({
url: "https://im2.io/eX4mp1E4pI/2600x2600,quality=low",
method: "POST",
data: {
file: image
},
processData: false,
contentType: false,
crossDomain: true
}).done(function(res) {
window.compressedImg = res;
formData.append("file", res);
runOCR();
}).fail(function(jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
};
Please note:
this (in my experience), will fail in the browser due to cross domain calls being blocked in the browser but not from cordova.
OCR compatible compression not added in yet (but would require a file size as well as dimension argument)
The output from this call is a raw png as a string, i.e. what you get when you open a .png file in a text editor. I've tried loads of ways to handle this but cannot understand how to use this data in the next ajax call (below), does it need to be saved to disk and then uploaded, if so - how? (because I tried writing it to localstorage but it would still be treated as a string).
The OCR.space call;
var formData = new FormData();
formData.append("language", "MYLANGUAGE");
formData.append("apikey", "MYAPIKEY");
formData.append("isOverlayRequired", false);
function runOCR2() {
jQuery.ajax({
url: 'https://api.ocr.space/parse/image',
data: formData,
dataType: 'form/multipart',
cache: false,
contentType: false,
processData: false,
method: 'POST',
success: function(ocrParsedResult) {
console.log(ocrParsedResult);
}
});
}
Please note; Vars are not set here but I keep them together in this question for clarity.
The response from this call is:
responseText: "{\"ParsedResults\":null,\"OCRExitCode\":99,\"IsErroredOnProcessing\":true,\"ErrorMessage\":\"No file uploaded or UR…"
i.e. the call works but the image parameter is not a valid image.
Any ideas on how to trea the returned string so that it is readable as an image for the next api call?
Usually when you are uploading files using formData you just pass file reference like
form.append('myfile',$("#fileInput").files[0]) and browser handles the encoding stuff behind the screens .It manually converts file to byte-stream and prepares appropriate boundary to help server distinguish where image begins and ends
but here scenario is different you don't have the file bound to any physical file control instead its created dynamically and you get a bytestream of that .To account for the above fact you need to tell browser explicitly that it's a independent raw binary stuff and should be treated as such
A Blob object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format.
var blob = new Blob([res], {type : 'image/png'}); //res is the converted image ImageOptim API
var formData = new FormData();
var fileName = 'myimage.png'; //filename that server will see it as
formData.append('anything', blob, fileName);
formData.append("language", "MYLANGUAGE");
formData.append("apikey", "MYAPIKEY");
formData.append("isOverlayRequired", false);
function runOCR2() {
$.ajax({
url: "https://api.ocr.space/parse/image",
type: "POST",
cache: false,
contentType: false,
processData: false,
data: formData,
success: function(response){alert(response);}
});
}

formData object not working with jquery AJAX post?

lets jump right into the code :
var formData = new FormData();
formData.append('name', dogName);
formData.append('weight', dogWeight);
formData.append('activity', dogActivity);
formData.append('age', dogAge);
formData.append('file', document.getElementById("dogImg").files[0]);
console.log(formData);
Here I am appending some strings and one file object to the formData object in order to send all the information asynchronous to the server.
Right after that I have this jquery ajax request :
$.ajax({
type: "POST",
url: "/foodoo/index.php?method=insertNewDog",
data: JSON.stringify(formData),
processData: false, // tell jQuery not to process the data
contentType: "multipart/form-data; charset=utf-8",
success: function(response){
console.log(response);
},
error: function(){
}
});
So here I am trying to POST the info to the server, on the server php file I have a simple print_r of the POST so I see what gets through and what not.
Unfortunately my response in the console.log(data) is empty.
Also if you check the HEADER in the Network tab you get the following empty output:
Success function gets called (just for clarification)
When you're sending an ajax request via jQuery and you want to send FormData you don't need to use JSON.stringify on this FormData. Also when you're sending file the content type must be multipart/form-data including boundry - something like this multipart/form-data; boundary=----WebKitFormBoundary0BPm0koKA
So to send FormData including some file via jQuery ajax you need to:
Set data to the FormData without any modifications.
Set processData to false (Lets you prevent jQuery from automatically transforming the data into a query string).
Set the contentType to false (This is needed because otherwise jQuery will set it incorrectly).
Your request should look like this:
var formData = new FormData();
formData.append('name', dogName);
// ...
formData.append('file', document.getElementById("dogImg").files[0]);
$.ajax({
type: "POST",
url: "/foodoo/index.php?method=insertNewDog",
data: formData,
processData: false,
contentType: false,
success: function(response) {
console.log(response);
},
error: function(errResponse) {
console.log(errResponse);
}
});
if you did exactly as pervious anwswer and still not working
dont worry its working
maybe intelligence and quick wath are telling you its not working
but dont worry, look at network tap
its working
hope this saves your time
//For those who use plain javascript
var form = document.getElementById('registration-form'); //id of form
var formdata = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open('POST','form.php',true);
// xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//if you have included the setRequestHeader remove that line as you need the
// multipart/form-data as content type.
xhr.onload = function(){
console.log(xhr.responseText);
}
xhr.send(formdata);

json_encode to send data back to js

Im creating a simple upload script. I use a simple form to let people upload a picture and then a external php script will upload the picture and return some vars to the upload page.
But I cant get the part to return some vars to work. currently im using this:
The page that also contains the form:
form_data.append('file', file_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(response){
document.getElementById("titel" + amount).innerHTML = response['naam'];
});
The upload page that should return some data:
echo json_encode(array('naam'=>$naam));
This scripts returns undefined..
If I remove the ['naam'] after response on the form page it will print out:
{"naam":"test.png"}
Hope someone know what im doing wrong.
Thanx in advance!
You said:
dataType: 'text', // what to expect back from the PHP script, if anything
… so jQuery will ignore what the server claims the data is (which seems to be HTML as you haven't changed the Content-Type header in your PHP) and process the response as if it was plain text.
response will therefore be a plain text string and not the results of parsing JSON.
Change dataType to "json".
The response you get from the server is the string. To use it as object, you need to parse it to JSON format using JSON.parse().
var obj = JSON.parse(response);
Then you can use:
obj.naam;
to get the value of naam from the object.
Please change datatype from "text" to "json" then parse that JSON using JSON.parse(//return value ").
Var jsonObject = JSON.parse("Ajax Response object");
then use it jsonObject.keyName and it will return the value.

Create a file from content of ajax post

I would like to have a php script that creates a file from the content of an ajax post. File to be called report.txt
I have this php script located at /var/www/copypaste.test/public_html/index.php
<?php
header('Access-Control-Allow-Origin: *');
$report = $_POST['report'];
echo $report;
$report_file = fopen("report.txt", "w");
fwrite($report_file, $report);
?>
and the i have a simple ajax post for now with some test text
var text = 'test string';
var formData = new FormData();
formData.append('report', text);
var ajax = jQuery.ajax({
type: "POST",
url: 'http://copypaste.test',
data: formData,
dataType: 'text',
processData: false,
contentType: false,
success: function(){
console.log('success');
},
error: function() {
console.log('error');
}
});
}
The ajax post is successful as i get test string in the response and this in my console
readyState 4
responseText "\ntest string"
status 200
statusText "OK"
when i then go to http://copypaste.test I don’t see the text or the creation of a file when going into the directory?
Could anyone point me in the right direction please
Thanks
I noticed that you never call fclose("report.txt") to close the file after writing. This can cause problems.
You can you use this function call to handle the opening, writing, and closing of a file.
file_put_contents("report.txt",$report);
You might try replacing the "report.txt" in the function call above just in case the file is still open in memory and you are not able to access it.

Categories