Alright, in this phonegap app I start with a huge image file from the device's camera.
Then I reduce the resolution and allow the user to crop it using javascript canvas and some very cool code called darkroomJS.
At the end darkroomJS uses toDataURL() method to get base64 data out of the canvas.
Now I need to upload it to Amazon S3.
I can upload a file from my computer to S3 using a form just fine. What I'm working on is sending the base64 data.
I also have a function that converts the base64 data into a blob. (which I've read will be required, but I'm open to other ideas).
<form action="https://mybucketname.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
<input type="" id="key" name="key" value="uploads/${filename}">
<input type="" id="AWSAccessKeyId" name="AWSAccessKeyId" value="YOUR_AWS_ACCESS_KEY">
<input type="" id="acl" name="acl" value="private">
<!-- <input type="" id="success_action_redirect" name="success_action_redirect" value="http://localhost/"> -->
<input type="" id="policy" name="policy" value="YOUR_POLICY_DOCUMENT_BASE64_ENCODED">
<input type="" id="signature" name="signature" value="YOUR_CALCULATED_SIGNATURE">
<input type="" id="Content-Type" name="Content-Type" value="image/jpeg">
<!-- <input id="file" name="file" > -->
<br>
<input type="submit" value="Upload File to S3">
</form>
I write in the credentials using jquery after they are obtained from my server. That part works fine.
The trouble is how do I put a blob in the form?
I've tried two methods.
Setting the value with jQuery.
$page.find("#file").attr('value', blobData);
//inserts the string [object Blob] text into the field and ships it to S3, not very useful
also I've tried:
var fd = new FormData(document.forms[0]);
fd.append('file', blobData);
//has no effect; S3 then complains that it was expecting a file, and didn't get one.
What am I doing wrong? How can I make this work?
Alright, got something that works:
I guess having the form actually rendered on the page kinda forces the browser to stringify the blob.
The function s3Man.getS3Policy just makes a AJAX request to my sever to get a signed s3 policy, keys, etc.
this.uploadBase64ImgToS3 = function(base64Data, filename, callback){
var xmlhttp = new XMLHttpRequest();
var blobData = dataURItoBlob(base64Data);
var contentType = false;
if (filename.match(/.png/)) var contentType = 'image/png';
if (filename.match(/.jpg/)) contentType = 'image/jpeg';
if (!contentType){
xStat.rec("content type not determined, use suffix .png or .jpg");
return;
}
s3Man.getS3Policy(filename, function(s3Pkg){
console.log("policy:", s3Pkg);
var fd = new FormData();
fd.append('key', s3Pkg.filename);
fd.append('acl', 'public-read');
fd.append('Content-Type', contentType);
fd.append('AWSAccessKeyId', s3Pkg.awsKey);
fd.append('policy', s3Pkg.policy);
fd.append('signature', s3Pkg.signature);
fd.append("file", blobData);
xmlhttp.open('POST', 'https://swoopuploadspublic.s3.amazonaws.com/', true);
xmlhttp.send(fd);
});
}
Related
I am trying to submit a form via ajax using the post method and a FormData object.
Here is a simplified version of the JavaScript:
var form=…; // form element
var url=…; // action
form['update'].onclick=function(event) { // button name="update"
var xhr=new XMLHttpRequest();
xhr.open('post',url,true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var formData=new FormData(form);
formData.append('update', true); // makes no difference
xhr.send(formData);
xhr.onload=function() {
alert(this.response);
};
};
The form has:
a button (type="button" name="update") to run the script
no action and method="get"
My PHP script has the following:
if(isset($_POST['update'])) {
print_r($_POST);
exit;
}
// more stuff
print 'other stuff';
When I try it, the PHP falls through to the rest of the code, and I get the other output, rather than what I expect from the print_r statement.
I have tried the following variations:
new FormData() (without the form). This does work if I add the update data manually.
new FormData(form). This does not work, whether I add the update manually or not.
changing the form method to post.
Firefox, Safari & Chrome on MacOS; all current versions.
The from itself looks something like this:
<form id="edit" method="post" action="">
<p><label for="edit-summary">Summary</label><input id="edit-summary" name="summary" type="text"></p>
<p><label for="edit-description">Description</label><input id="edit-description" name="description" type="text"></p>
<p><label for="edit-ref">Reference</label><input id="edit-ref" name="ref" type="text"></p>
<p><label for="edit-location">Location</label><input id="edit-location" name="location" type="text"></p>
<p><button type="button" name="update">OK</button></p>
</form>
What should I do to submit the get this to work?
No jQuery, please.
The content type when sending a FormData object is multipart/form-data not url encoded.
Further more the proper boundary must be set for the request, which the user is unable to do. For this XMLHttpRequest sets the correct content type with the required boundary.
So all you have to do is not set the content type and it'll work.
var xhr=new XMLHttpRequest();
xhr.open('post',url,true);
//xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");<--don't do this
var formData=new FormData(form);
formData.append('update', true); // makes no difference
xhr.send(formData);
xhr.onload=function() {
alert(this.response);
};
Change the name of the button to something other than "update" (and change it in your form['update'].onclick... as well). I think its clashing with the value you are trying to set on the FormData to trigger the PHP code.
I'm trying to upload files using PHP script on the server as the upload handler. It works just fine with a traditional web form like this:
<form action="uploadHandler.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
But when I try to switch to a drag-and-drop form the PHP handler is failing with an undefined index on the name value "fileToUpload". Here is the error message:
PHP Notice: Undefined index: fileToUpload in /home/...../uploadHandler.php on line 10
Line 10 of uploadHandler.php contains this statement:
$fileName = $_FILES['fileToUpload']['name'];
I'm still using the name=fileToUpload in my drag and drop form:
<form class="my-form">
<p>Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region</p>
<input type="file" id="fileToUpload" name="fileToUpload" onchange="handleFiles(this.files)">
<label class="button" for="fileElem">Select some files</label>
</form>
This is the function on the page that contains the drag and drop form that calls the uploadHandler:
function uploadFile(file, i) {
var url = 'https://xxxxxx/uploadHandler.php'
var xhr = new XMLHttpRequest()
var formData = new FormData()
xhr.open('POST', url, true)
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
formData.append('file', file)
xhr.send(formData)
}
I tried adding something like formData.append('name', 'fileToUpload') before calling xhr.send, but that didn't seem to help.
What am I missing?
I'm creating a feedback form, where the user can record their screen about an error or idea.
I made this using getDisplayMedia and mediarecorder which is then saved into a webm blob url.
Initially, we gave the user a download file of that recording and the user had to manually put it into file input, but I was wondering if it's possible to fetch that video from the blob url and submit along the form without user having to download the file or does this pose a security issue?
This has to work only on Mozilla and Chrome and if there's vanilla JS solution to this, it would be appreciated.
So, right now I have a working blob uri that is passed to the form as url parameter and now i need to get that blob video and attach it to the form so I can send it as an attachment in an email
(value $(Q:attachment) is the uri parameter that gets passed)
var blob = new Blob(recordedChunks, {
type: 'video/webm'
});
var attachment = URL.createObjectURL(blob);
<form name="feedbackform" action="/submit" method="post" enctype="multipart/form-data">
<input type="hidden" name="video_attachment_url" id="video_attachment_url" value="$(Q:attachment)">
<input type="submit" value="Send">
<input type="button" value="Cancel" onClick="window.close();">
</form>
I have a Java servlet that receives a file, processes it and then writes the resulting file back through HttpServletResponse's OutputStream.
For upload, I use a simple form:
<form id="upload-form" action="MyServlet" method="POST" enctype="multipart/form-data">
Select file to convert:
<input type="file" id="file-select" name="myfile" />
<button type="submit" id="upload-button">Upload</button>
</form>
After the file has been processed, a download dialog opens automatically.
Since processing may take a while (something like 30 seconds plus upload time), I wanted to provide some progress information through a websocket on the same page. This works if I do this:
var uploadForm = document.getElementById("upload-form");
var fileSelect = document.getElementById("file-select");
var uploadButton = document.getElementById("upload-button");
var httpRequest = new XMLHttpRequest();
uploadForm.onsubmit = function(event) {
event.preventDefault();
event.stopPropagation();
var file = fileSelect.files[0];
var formData = new FormData();
formData.append("myfile", file, file.name);
httpRequest.open("POST", "MyServlet", true);
httpRequest.send(formData);
};
The essential commands here seem to be event.preventDefault and event.stopPropagation.
The thing is: with this code, I get my progress info - but my download window never appears. If I comment out the two commands, it's the other way around. What happens by default when submitting a form, and (how) can I trigger that manually, so that I get both progress info AND the resulting file?
Note: I'm not using jQuery so far.
I am implementing the dropzone.js file upload. However I do not want dropzone to handle the uploads because it seems like they go in bursts instead of all at once. I would like my photos to be uploaded at one time. To do so users will drag and drop photos into the dropzone area. From here they choose some custom options on the images. Then I would like a user to hit a custom button. This button can perform the following.
Add photos to multiImg[] array
invoke form
After a photo is uplaoded into the dropzone I will have access to all the information about the photo. Name, size, location(on uers computer). I am just unsure how to accomplish step 1 which is to take the photos and pass them into a form via javascript.
Is this even a good approach?
<form method="post" action="" enctype="multipart/form-data">
<input type="file" accept='image/*' name="multiImg[]" id="multiImg" />
Or possibly programatically appending
<input type="file" accept='image/*' name="Img" id="Img" />
Tags to the form and then submitting the form when done would be acceptable as well.
Can you dynamically add to the FileList for an input?
This got me closer to a solution.
xhr = new XMLHttpRequest();
formData = new FormData();
formData.append("" + paramNm + (this.uploadMult ? "[]" : ""), file, fileName);
xhr.send(formData);