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.
Related
So currently I'm working on a simple project where users gets to upload an image to server. Before I mention my problem here is how I'm doing it:
Client:
var dataURL = sendingcanvas.toDataURL("image/*");
var imagedatatosend = dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
formdata = {
'image': imagedatatosend
};
$.ajax({
url: '../receive',
type: 'POST',
data: formdata,
encode: false,
success: function(result){
alert(result);
}
});
FYI: imagedatatosend size is lower than 5MB and contains exactly the file data selected.
Basically What happens Is that users select an image using <input type="file" tag Then I'm setting that selected file drawn in a canvas to convert it to base64 and send it to server.
Java Server:
String datareceived = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
byte[] bImg = Base64.decodeBase64(datareceived.getBytes("UTF-8"));
FileOutputStream fos = new FileOutputStream("hi.jpg");
fos.write(bImg);
fos.close();
I think I might not need to explain what the code above does. But I'm facing some serious performance problem I mean It takes some huge time to write the data to hi.jpg file, even if I try System.out.println(datareceived); It takes seconds for my mouse click to respond on server console.
I don't know why is it happening, Do I need to send the image data as multipart or what?
All replies are appreciated and Thanks in Advance:)
Use XMLHttpRequest and FormData to append the file. It will be sent using multipart and chunked appropriately.
See: https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
When I try to upload a MP4 video with 16.9 MB size, using ajax async post to an PHP file the console triggers an error saying: POST http://website.com/proc_vids.php net::ERR_EMPTY_RESPONSE
I know for a fact that this problem is related with PHP memory_limit because when I set to 200 MB it's all fine but when I change it back to 100 MB this error happens.
I can't even get the POST to an PHP variable because as soon as the ajax post call is made it triggers the error without even doing anything on server side (PHP). Here is the ajax post code:
var proc = 1;
video = document.getElementById('preview_video').src;
$.ajax({
'async': true,
'type': "POST",
'global': false,
'dataType': 'json',
'url': "proc_vids.php",
'data': {proc: proc, video: video}
}).done(function () {
//Do something
});
PHP code:
$proc = $_POST['proc'];
if ($proc == 1){
//$video = $_POST['video'];
}
As you can see I commented the line where I pass the POST to a variable and still triggering the error.
What can I do to the video variable containing the base64 code to not expand consuming such high memory levels?
Is there any alternatives without setting the memory_limit higher?
Problem solved thanks to cmorrissey!
I used the same method as described in this thread: Convert HTML5 Canvas into File to be uploaded?
Sending AJAX POST as a FormData and converting the base64 data to Uint8Array into a blob is the key to not allocate PHP memory when the POST is made. But be careful tho because older browsers may not support blob.
Thank you guys ;)
I am trying to use BusinessObject RESTful API to download a generated (pdf or xls) document.
I am using the following request:
$.ajax({
url: server + "/biprws/raylight/v1/documents/" + documentId,
type: "GET",
contentType: "application/xml",
dataType: "text",
headers: {"X-SAP-LogonToken": token, "Accept": "application/pdf" },
success: function(mypdf) {
// some content to execute
}
});
I receive this data as a response:
%PDF-1.7
%äãÏÒ
5 0 obj
<</Length 6 0 R/Filter/FlateDecode>>
//data
//data
//data
%%EOF
I first assumed that it was a base64 content, so in order to allow the users to download the file, I added these lines in the success function:
var uriContent = "data:application/pdf; base64," + encodeURIComponent(mypdf);
var newWindow=window.open(uriContent, 'generated');
But all I have is an ERR_INVALID_URL, or a failure while opening the generated file when I remove "base64" from the uriContent.
Does anyone have any idea how I could use data response? I went here but it wasn't helful.
Thank you!
. bjorge .
Nothing much can be done from client-side i.e. JavaScript.
The server side coding has to be changed so that a url link is generated (pointing to the pdf file) and sent as part of the response. The user can download the pdf from the url link.
You cannot create file using javascript, JavaScript doesn't have access to writing files as this would be a huge security risk to say the least.
To achieve your functionality, you can implement click event which target to your required file and it will ask about save that file to user.
I have an endpoint from our Django backend guys with documentation that reads:
POST to /api/1/photo-uploads/ with enctype="multipart/form-data" with files in field called "files[]".
I've been attempting to send uploaded files with formData using jquery's AJAX method. I continue to get an error indicating that the file was not sent. When I view the payload I see.
undefined
------WebKitFormBoundary9AzM2HQPcyWLAgyR
Content-Disposition: form-data; name="file"; filename="auzLyrW.jpg"
Content-Type: image/jpeg
Which doesn't necessarily mean that it hasn't sent but there certainly isn't a location being posted. And I don't have any kind of verification that the file is uploaded.
var formData = new FormData();
formData.append('file', $('#file-upload').get(0).files[0]);
$.ajax({
url: '/api/1/photo-uploads/',
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
});
When I console.log formData it simply show's the prototype methods like .append. So I'm unable to verify if the file's data is being sent beyond checking the payload. I can log $('#file-upload').get(0).files[0] but I only see details from the file itself. Because I'm testing it locally an upload location should be something like localhost:8000/.
The backend guys are under the impression that it's something I'm doing. When I do a simple form post it works fine. I've tried a number of plugins and basic methods and all have produced the 400 {"message": "No photos supplied.", "success": false}
Any ideas would be appreciated.
The documentation asked that it be called files[]. What was being sent was file.
formData.append('files[]', $('#file-upload').get(0).files[0]);
I'm using Laravel 3, and I am AJAXing in a user comment. We are adding images to this comment and I can't seem to get the File Data to go through. When I set processData to false, I am also unable to access the other data such as the comment and privacy. Any insight?
var commentforms = $('form.compose');
commentforms.on('submit', function(e){
e.preventDefault();
var file = document.getElementById('file_input').files[0];
$.ajax({
type: 'POST',
url: '/issue/comment/' + issue_id,
processData: false,
data: {
side: side,
comment: comment,
privacy: privacy,
file: file,
},
success: function(response){
console.log(response);
new_comment = comment_template(response);
updateSide(new_comment);
},
});
Going off of what Kevin B commented, there are a couple ways to do this.
First, the reason it is not working is that, by default, you cannot send files with an AJAX request. That is it, and that is why it isn't working. No matter what you do to your form and your AJAX request, you are stuck. (AJAX here meaning NOT XMLHttpRequest2)
SOLUTION 1
Kevin B recommended the Javascript formData object which is part of the XMLHttpRequest Level 2. Information on how to use it can be found: https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects
In relation to your code, you code do something along the lines of:
commentforms.on('submit', function(e){
e.preventDefault();
var oData = new FormData(document.forms.namedItem("composeForm"));
var oReq = new XMLHttpRequest();
oReq.open("POST", '/issue/comment/' + issue_id, true);
//on a side note, issue_id isn't declared anywhere...
oReq.onload = function(oEvent) {
if (oReq.status == 200) {
console.log("Uploaded!");
} else {
console.log("Error " + oReq.status + " occurred uploading your file.");
}
};
oReq.send(oData);
});
PROBLEM
Again, as Kevin B said, it isn't widely supported. Checking here: http://caniuse.com/xhr2 you can see that IE9 and below isn't supported, which is XP, Vista, and non-upgraded Windows 7. If your app is on your own controlled network, and you can ensure everyone is using Firefox/Chrome/IE10+, you are good to go. If you are going to be using this feature with the public, then you need another solution.
OTHER SOLUTIONS
Many sites currently use AJAX to upload files, or trick you into thinking it is AJAX. What other websites do is one of two things: hidden iFrames or Flash.
The hidden iFrame trick is to create an iframe that populates the data of your current form, and then sends it off like it normally would, meaning a page reload. Because it is in an iFrame and hidden, the user never sees the page reload and the content is uploaded like you would expect.
The Flash trick is to use a little Flash app/plugin that finds the file and then sends it to your server. It is fairly easy to use, and since Flash is widely supported, it can do the trick on most browsers. You just have to include the plugin and you are good to go.
Plugins
I prefer to use plugins, as they do all the hard work for me. The one I am fond of right now for it's simplicity is Fine Uploader. It is easy to configure, looks great, can be Bootstrapped, or used with jQuery. Plugins may use one or both methods to upload the files, or they may even try the XMLHttpRequest2 first, then fall back on one of the other methods to upload the files. Ultimately, most of the popular plugins are easy to configure and provide fairly decent documentation to get it to do what you want.
Other popular plugins:
Uploadify
BlueImp
Plupload
read this:
With XHR2, File upload through AJAX is supported. E.g. through
FormData object, but unfortunately it is not supported by all/old
browsers.
Try with this:
Tutorial
And see this code:
var data= new FormData();
data.append( 'file', $('#file') );
$.ajax({
url: 'file.php',
data: data,
processData: false,
contentType: false,
type: 'POST',
success: function(response){
console.log(response);
}
});
Suerte!