how to upload to remote folder saved audio from html5 getusermedia microphone - html

I have this file thats created with html5, I am just starting to learn.
Basically when I am recording from the microphone and stop the record I am finding it hard to upload the outputted file to a folder on the server.
Here is the page i am testing on.
http://2click4.com/playground.php

You use Blob and createObjectURL in your code on example page. You create ObjectURL, so you can send it by XMLHttpRequest to server:
var blob = new Blob ( [ view ], { type : 'audio/wav' } );
// let's save it locally
outputElement.innerHTML = 'Handing off the file now...';
var url = (window.URL || window.webkitURL).createObjectURL(blob);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'link_to_server', true);
xhr.onload = function (e) {
var result = e.target.result;
};
xhr.send(url);//url is Blob

Related

chrome PDF viewer can't download file

Here is my situation, I got a server running a PDF generator, when I make a request with some params, it will give me back a PDF file, the PDF is not stored in the server it's generated during the runtime.
Everything goes fine, I can get the PDF open in chrome's PDF viewer, but if want to download the file, an error occurred, like the image shows.
Because Chrome go to the origin URL to request the file, but the file is not a static resource on the server.
I don't know if anybody has run into this problem?
Whenever you leave the website you used to create the object URL (window.URL.createObjectURL(...)) that very object will get garbage collected. So you need to keep a reference to that object somehow.
This works for us in Chrome, Firefox, Safari, iOS Safari & Android to first display the PDF in capable browsers in a new tab and allow a download afterwards (in IE it just starts the download):
function openPdfInNewTab(url,
postData,
description = 'Document',
filename = description + '.pdf') {
if (!window.navigator.msSaveOrOpenBlob) {
var tabWindow = window.open('', '_blank');
var a = tabWindow.document.createElement('a');
a.textContent = 'Loading ' + description + '..';
tabWindow.document.body.appendChild(a);
tabWindow.document.body.style.cursor = 'wait';
} else {
spinnerService.show('html5spinner');
}
$http.post(url, postData, {responseType: 'arraybuffer'})
.then(function showDocument(response) {
var file = new Blob([response.data], {type: 'application/pdf'});
if (window.navigator.msSaveOrOpenBlob) {
spinnerService.hide('html5spinner');
window.navigator.msSaveOrOpenBlob(file, filename);
} else {
tabWindow.document.body.style.cursor = 'auto';
var url = a.href = window.URL.createObjectURL(file);
a.click();
a.download = filename;
}
$timeout(function revokeUrl() {
window.URL.revokeObjectURL(url);
}, 3600000);
}, handleDownloadError);
}
We have been opening PDFs in a new browser-tab and had similar issues.
For us it started working again when we use window.URL.createObjectURL instead of tabWindow.URL.createObject which displayed the PDF but didn't allow the download.
Chrome's built in PDF viewer will download the pdf file through the PDF's origin URL. So if the PDF is generated at server runtime and if it's not stored in the sever, the download could fail.
see link here: https://productforums.google.com/forum/#!topic/chrome/YxyVToLN8ho
Just as an additional comment:
We had the same problem on a project, on Chrome only.
Authenticated GET request would fetch the PDF as an attachment from API, and we would forward it via window.createObjectURL(blob) to the browser viewer.
The Network Error was due us invoking window.revokeObjectURL(url); after opening the PDF. When we removed that line, the blob wasn't garbage collected immediately after opening.
fetch(request)
.then(async response => {
if (!response.ok) {
return reject(response.statusText);
}
const blob = await response.blob();
const url = await window.URL.createObjectURL(blob);
window.open(url, '_blank');
URL.revokeObjectURL(url); // This line was causing the problem
resolve();
})
.catch(reject)

Is there a workaround for CORS when using XMLHttpRequest with a local file?

I'd like to use Exif.js to read JPEG EXIF tags from a local file. However, the javascript lib uses XMLHttpRequest to read JPG files as a BinaryFile:
function getImageData(oImg, fncCallback)
{
BinaryAjax(
oImg.src,
function(oHTTP) {
var oEXIF = findEXIFinJPEG(oHTTP.binaryResponse);
oImg.exifdata = oEXIF || {};
if (fncCallback) fncCallback();
}
)
}
When I use <input type="file"> I get an HTML5 File object which I can read using a FileReader but I don't know how to convert this to a BinaryFile:
_initHTML5FileReader = function() {
var chooseFile;
chooseFile = document.getElementById("html5-get-file");
chooseFile.onchange = function(e) {
var file;
file = e.currentTarget.files[0];
var reader;
reader = new FileReader();
reader.onloadend = function(ev) {
var dataUrl = ev.target.result;
// How do I change this to a BinaryFile???
};
reader.readAsDataURL(file);
return false;
};
};
But I also using AppGyver Steroids (PhoneGap) which serves my page from http://localhost/index.html, and when I try to use Exif.js, I get this CORS error:
XMLHttpRequest cannot load data:image/jpeg;base64,/9j/4X2cRXhpZgAASUkqAAgAAAAOAA8BAgAKAAAAtgAAABABAgAI…N6gn14dm6BmJyMdYaMhX16hI+HgIWLj5aWkJOaiHF7hoV+dnBwc3Jzbm14hGlZcIaWlXFEU3OB. Received an invalid response. Origin 'http://localhost:4000' is therefore not allowed access.
Is there any way to configure XmlHttpRequest to serve a local File object without the CORS error?

Using backgrounddownloader and savefilepicker together?

Hello everyone I have a small winrt aplication that downloads video from internet and I was trying to implement backgrounddownloader and filesavepicker together but I run on errors for every type of implementation I searched google and I searched microsoft documentation but nothing.I implemented download via HttpClient class but what I want is to get download progress and HttpClient doesn't offer it.Thx in advance
Here's a quick sample, how to do it:
// set download URI
var uri = new Uri("http://s3.amazonaws.com/thetabletshow/thetabletshow_0072_lhotka.mp3");
// get destination file
var picker = new FileSavePicker();
// set allowed extensions
picker.FileTypeChoices.Add("MP3", new List<string> { ".mp3" });
var file = await picker.PickSaveFileAsync();
// create a background download
var downloader = new BackgroundDownloader();
var download = downloader.CreateDownload(uri, file);
// create progress object
var progress = new Progress<DownloadOperation>();
// attach an event handler to get notified on progress
progress.ProgressChanged += (o, operation) =>
{
// use the progress info in Progress.BytesReceived and Progress.TotalBytesToReceive
ProgressText.Text = operation.Progress.BytesReceived.ToString();
};
// start the actual download
await download.StartAsync().AsTask(progress);
You should be able to modify it for your needs from here on.

Upload a file to Google Drive API using HTML5

I'm creating a Google Chrome extension which use Google Drive API.
I have to upload a file with HTML5.
For text files, there is no problem. But when I want to upload a binary file, there are always errors.
So when I upload a file using the FileReader in HTML5 as BinaryString, my image is corrupted, I can't read it.
And when I use Base64 encoding (with the header in the body part "Content-Transfer-Encoding: base64"), I have a 400 Bad Request -> Malformed multipart body.
Can you help me please ?
Thanks :)
PS: I don't want to use Google Drive SDK, I prefer write all the code.
var bb, reader;
var meta = {
"title": "mozilla.png",
"mimeType": "image/png",
"description": "Mozilla Official logo"
};
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://developer.mozilla.org/media/img/mdn-logo-sm.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e){
if(this.status == 200){
bb = new WebKitBlobBuilder();
bb.append(this.response);
console.log('Download OK');
reader = new FileReader();
reader.readAsDataURL(bb.getBlob('image/png'));
reader.onloadend = function(e){
console.log('Reader OK');
var bound = 287032396531387;
var parts = [];
parts.push('--' + bound);
parts.push('Content-Type: application/json');
parts.push('');
parts.push(JSON.stringify(meta));
parts.push('--' + bound);
parts.push('Content-Type: image/png');
parts.push('Content-Transfer-Encoding: base64');
parts.push('');
parts.push(reader.result);
parts.push('--' + bound + '--');
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart", true);
xhr.setRequestHeader("Authorization", "Bearer token123456");
xhr.setRequestHeader("Content-Type", "multipart/mixed; boundary=" + bound);
xhr.onload = function(e){
console.log("DRIVE OK", this, e);
};
xhr.send(parts.join("\r\n"));
}
}
};
xhr.send();
For Binary Upload, just modify this line :
reader.readAsDataURL(bb.getBlob('image/png'));
by that
reader.readAsBinaryString(bb.getBlob('image/png'));
and delete this line :
parts.push('Content-Transfer-Encoding: base64');
I tried to create a file by sending the metadata first and upload the content after like in this post and I always get a 404 error for uploading the content, but this is another story...
An empty line which consists of only \r\n and no other whitespace need to be added at the end of your request. Try to add another parts.push(''); after parts.push('--' + bound + '--');
Edit:
First, I want to say that you should not upload file as raw Binary String because your binary data contains control characters which may screw up your request and results in corrupted file. Data should be encoded in Base64. You can read more here
If you check reader.result in debug, it will contain:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABHCAMAAABoMgR/AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJlQTFRFAAAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAEgICExAQIAQFIyAgLwYHMjAwPggJQkBATAoLUlBQWwwOYmBgaQ4QcXBweBASgYCAhxIUkIKCkY+PlRQXoZ+fpBYZrYaGsK+vsxgbwL+/wRod0Bwg0M/P3h4i4N/f7SAk7+/v9pCS////7yG8VgAAAA90Uk5TABAgMEBQYHCAn6+/z9/vBoviEQAABBtJREFUWMOtmA13mzoMhumWdd3uWpuPACUEWIkXA3HI+P8/7kq2AYOBNj1Tz2nA9oOl10KAHUfZw+7p4/b41ZnY7j9yn708PQzww09yv7186+lf5FP2qHBJJ1y0H7am9JCR8z/BAa3bOy1B/zH+lzW6KJt3+CfHeYSfYqGboX9eylRMC5FB/7Pj/IBRdicPoTkOMMIgZWlAEmtIBn1fHFjx0JIGPQt40wiWSZGoZ/Mc2ncLuMgoABAQpXCWEi9hraAWv4KXFP1G1dIYBVSy1ha/iHOM12PzmdLU4hfwBhUj6VRKnqA/GfBxvYWLVCbjMDVLwrBoUOM9/JXAw0rWazgqhp63LMTIa4+mjBdeCiMl2IoyNq4wxWWaoGUwGzjASKxiKALwq6gHj+AK5RyXaaIMZoaxgga9AmlipWu5LJ1ISKwZNYVsnEmeeR66Z+O45KzPaBF7ujkkibkWRSiC0MbVkusxhLShbOesxcCCjI+J1WYWLhItXI9DAy5ASNtel3C4hIUXtBeOyduXkpKTgPGYZI3qqU6R319ihgtIELCABBi1ktcTMvvTNtZ4lXent1fpRRIuSVfj7Jzrw6ARnDcYlEyJox9dSHeqLsdXlyzimVF4CqyfWZYCmkBtxHzz96RyT+djl5PUxmXexaO+ZEhDfdfJ4nNwo4qQeo43Wt/WiERaahZodMJ1UaIJLrJ+LmZ6rxesqM1bn6oQTbzm0goyJii4ystErydN+qqNpSwUK9WGDmkndAbWKuS+akN+6Fpk4zKEelCud4SNzzVQNxMr1UY9ubTQsSEDRFCXiewN16pNraUPWsFl0tP5Hd6USbla61A6Jp9YWG2YIaIZyGalDWXe1BCennCQkX4Ah0rrieEBaJQIU4hVnI2612b6yhR69xnX0PGOyUbfOWVts+D9DBeBMWMw+s7wmsHgl41TXSuGwHG2YP4w98KpBT3e2/iOUszfOOrll6sJXppKN9aryBru59J+/x1sciLtTz63Q49H3Wes+nf4Fby59h2nPD+pJmln1QHnZ8VBWzXF8fig6SsZmrRFFz0b/kKdJSS3cVIp/NXCiXtR5/stPBpimuPkVZ/nGziRsUUGjhes9tjQD7ls4D7qRma41AIwPeS2jpO3rvMtvFO66CHHDdy95eQdnFTrODzB3sX94zLu9/3ruBziLuORctw9r+N5pKdYwm/y4m/VBn5113G5aPtuC+/OGzimTGXhp3Hdc5XSa/gF7xsD31fV+eiOWQfUzV3Hu/w2wQc7DPiQ+wrHL6mbEegivr+NeKfX/Si/pL7Jk03cR59GHBcol/+f1Veke7m/VmGl/A74d0yV6jP0s/yGl5X+cL7eUSXffFXl/8H3u/Pw4zO7Bztj7+Le7YdnY+9C7Zw8fnznZDfsnPwP488L21waSrUAAAAASUVORK5CYII=
As you can see, the readAsDataURL method DID encode your data to base64 but because it is used to produce Data URI , a string with format as data:[<MIME-type>][;charset=<encoding>][;base64], is added at the begin of your encoded data. This is the culprit cause 400 Bad Request error (Malformed multipart body).The solution is to eliminate this string before adding it to the request body:
parts.push(reader.result.replace(/^data:image\/(png|jpg);base64,/, ""));
I have tested and it works fine.

Send Image File via XHR on Chrome

I'm using HTML5 drag&drop to get images from a user's computer and want to upload them to my Rails server (using Carrierwave on that end). I don't know exactly what I'm doing here, but cobbled together this code from these instructions http://code.google.com/p/html5uploader/wiki/HTML5Uploader
This returns a 500 error - can anyone take a look and help me out with what I'm doing wrong?
var files = e.dataTransfer.files;
if (files.length){
for (var i = 0; i<files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function() {
var bin = reader.result;
var xhr = new XMLHttpRequest();
var boundary = 'xxxxxxxxx';
xhr.open('POST', '/images?up=true&base64=true', true);
xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);
xhr.setRequestHeader('UP-FILENAME', file.name);
xhr.setRequestHeader('UP-SIZE', file.size);
xhr.setRequestHeader('UP-TYPE', file.type);
xhr.send(window.btoa(bin));
};
};
};
There are a couple of things that could be the culprit. You're reading the file as a binary string, then creating a multipart request, then sending a base64 encoded value.
There's no need to read the file or mess with base64 encoding. Instead, just construct a FormData object, append the file, and send that directly using xhr.send(formData). See my response here.