I am using yeoman angular fullstack and im trying to do a simple file upload. I read the file from a form and i get it into the front end just fine
this.$scope.add = function() {
var f = document.getElementById('resume').files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
console.log(e.target.result);
Auth.saveResume({
data: e.target.result,
name:theFile.name
});
};
})(f);
reader.readAsArrayBuffer(f);
}
in auth.services.ts i have
saveResume(resume, callback?: Function) {
console.log(User)
return User.saveResume({ id: currentUser._id }, {resume},
function() {
console.log('auth.service in function');
console.log('currentUser._id: ' + currentUser._id);
return safeCb(callback)(null);
},
function(err) {
return safeCb(callback)(err);
}).$promise;
},
it successfully makes it into my back end controller
router.put('/:id/resume', auth.isAuthenticated(), controller.saveResume);
where i have a saveResume function
export function saveResume(req, res){
console.log(typeof req.body.resume.data);
console.log(typeof req.body.resume.name);
}
In the save resume function when i access the "name" parameter it is correct and is of type string. However when i access "data" i just get an object. I would like data to be either a file or buffer so i can upload it to s3.
My only guess for why its an object instead of an ArrayBuffer is that i think node doesnt support javascript ArrayBuffers, blobs, or files. How do i get the file in the backend in some form that s3 will accept? ie file, blob, or buffer
As #bubblez suggest i encoded it to base 64 like so
var fileReader = new FileReader();
var base64;
// Onload of file read the file content
fileReader.onload = function(fileLoadedEvent) {
base64 = fileLoadedEvent.target.result;
// Print data in console
console.log(base64);
Auth.saveResume(f.name, base64);
};
// Convert data to base64
fileReader.readAsDataURL(f);
i also changed auth so that it takes two separate parameters
saveResume(name, data, callback?: Function) {
console.log(User)
return User.saveResume({ id: currentUser._id }, {name, data},
function() {
console.log('auth.service in function');
console.log('currentUser._id: ' + currentUser._id);
return safeCb(callback)(null);
},
function(err) {
return safeCb(callback)(err);
}).$promise;
},
i then decode from base 64
export function saveResume(req, res){
var base64String = req.body.data.split(';base64,').pop();
console.log(base64String);
var buf = Buffer.from(base64String, 'base64').toString('utf');
uploadParams.Body = buf;
}
and this works!
Related
I am trying to capture the audio that's uploaded by the user, convert it to Blob then using wavesurfer.js to display the waveform.
I am following this instruction here https://bl.ocks.org/nolanlawson/62e747cea7af01542479
And here is the code
// Convert audio to Blob
$('#audioFileInput').on('change', function () {
var file = $('#audioFileInput')[0].files[0];
var fileName = file.name;
var fileType = file.type;
var fileReader = new FileReader();
fileReader.onloadend = function (e) {
var arrayBuffer = e.target.result;
blobUtil.arrayBufferToBlob(arrayBuffer, fileType).then(function (blob) {
console.log('here is a blob', blob);
console.log('its size is', blob.size);
console.log('its type is', blob.type);
surfTheBlob(blob);
}).catch(console.log.bind(console));
};
fileReader.readAsArrayBuffer(file);
});
But it says
blobUtil.arrayBufferToBlob(...).then is not a function
Another issue is that since the user might upload the audio themselves, the audio type might vary, expected to come from native device audio recorder. Anyone can help please? thanks.
A File object, like the ones you get in the input.files FileList, is already a Blob:
inp.onchange = e =>
console.log(inp.files[0] instanceof Blob) // true
<input type="file" id="inp">
So all you really need is to pass directly this File to your library:
$('#audioFileInput').on('change', function () {
var file = this.files[0];
surfTheBlob(file);
});
Found the answer already.
// Convert audio to Blob
$('#audioFileInput').on('change', function () {
var file = $('#audioFileInput')[0].files[0];
var fileName = file.name;
var fileType = file.type;
var url = URL.createObjectURL(file);
fetch(url).then(function(response) {
if(response.ok) {
return response.blob();
}
throw new Error('Network response was not ok.');
}).then(function(blob) {
surfTheBlob(blob);
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ', error.message);
});
});
Cheers!
as title description.
I'm trying to take a file from js, send it to my web api, and save it as a file on the server.
in my js, i first take the files, an convert them to a object with the file prop, and a base64 string
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = (function (theFile) {
return function (e) {
var newFile = { name : theFile.name,
type : theFile.type,
size : theFile.size,
lastModifiedDate : theFile.lastModifiedDate
}
console.log("e")
console.log(e)
console.log(theFile);
var binaryString = e.target.result;
updloadedFile(newFile, binaryString);
};
})(f);
reader.readAsDataURL(f)
Then i try to post it to my api, Sry there is a little angular mixed in here, but it should work like this anyway
function updloadedFile(file,data)
{
var dummyobj = {
Name: file.name,
Extension: file.type,
Path: "",
DataString: data,
}
$http.post('/api/FileBrowser/UploadedFiles/' + $rootScope.User.App_ID,
JSON.stringify(dummyobj),
{
headers: {
'Content-Type': 'application/json'
}
}
).success(function (data) {
}).error(function (data, status, headers, config) {
});
}
At last at my server, i try to take the DataString an convert it to a file
[HttpPost]
public void UploadedFiles(Int64 id, [FromBody]FileModel value)
{
try
{
var path = HttpContext.Current.Server.MapPath("~/gfx/Files/" + id + "/");
File.WriteAllBytes(path+"\\"+value.Name, Convert.FromBase64String(value.DataString));
}
catch (Exception ex)
{
throw;
}
}
But here it throw a exception with the messeage
The input is not a valid Base-64 string as it contains a non-base 64
character, more than two padding characters, or an illegal character
among the padding characters.
My base-64 string look like this in the web api
data:image/gif;base64,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
You need to remove data:image/gif;base64, before decoding, you can do this in javascript:
updloadedFile(newFile, binaryString.replace('data:image/gif;base64,', ''));
or in C#
File.WriteAllBytes(path+"\\"+value.Name, Convert.FromBase64String(value.DataString.Replace("data:image/gif;base64,", "")));
As jcubic mention, you need to remove the type tag.
A more dynamic way to remove the tag is to split on ;base64, and take last element. Should work for multiple types, instead of being hardcoded for gif files.
const GetBase64 = (file: any) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
var base64 = `${reader.result}`.split(';base64,').pop();
resolve({name: file.name, size: file.size,type: file.type, content: base64})
};
reader.onerror = error => reject(error);
});
};
I am using ngCordova Capture to write this code by recording audio and send the base64 somewhere (via REST). I could get the Capture Audio to work but once it returns the audioURI, I cannot get the data from the filesystem as base64. My code is below:
$cordovaCapture.captureAudio(options).then(function(audioURI) {
$scope.post.tracId = $scope.tracId;
$scope.post.type = 'audio';
console.log('audioURI:');
console.log(audioURI);
var path = audioURI[0].localURL;
console.log('path:');
console.log(path);
window.resolveLocalFileSystemURL(path, function(fileObj) {
var reader = new FileReader();
console.log('fileObj:');
console.log(fileObj);
reader.onloadend = function (event) {
console.log('reader.result:');
console.log(reader.result);
console.log('event.result:');
console.log(event.result);
}
reader.onload = function(event2) {
console.log('event2.result:');
console.log(event2.target.result);
};
reader.readAsDataURL(fileObj);
console.log(fileObj.filesystem.root.nativeURL + ' ' + fileObj.name);
$cordovaFile.readAsDataURL(fileObj.filesystem.root.nativeURL, fileObj.name)
.then(function (success) {
console.log('success:');
console.log(success);
}, function (error) {
// error
});
});
Here is the output in console log:
So how do I get the base64 data from the .wav file?
I have been reading these links:
PhoneGap FileReader/readAsDataURL Not Triggering Callbacks
https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
http://jsfiddle.net/eliseosoto/JHQnk/
http://community.phonegap.com/nitobi/topics/filereader_onload_not_working_with_phonegap_build_2_5_0
Had same problem, which I fixed using both the Cordova Capture and Cordova File plugin.
navigator.device.capture.captureAudio(function (audioFiles) {
var audioFile = audioFiles[0],
fileReader = new FileReader(),
file;
fileReader.onload = function (readerEvt) {
var base64 = readerEvt.target.result;
};
//fileReader.reasAsDataURL(audioFile); //This will result in your problem.
file = new window.File(audioFile.name, audioFile.localURL,
audioFile.type, audioFile.lastModifiedDate, audioFile.size);
fileReader.readAsDataURL(file); //This will result in the solution.
});
I have the following code to upload to my Node.js/Express.js backend.
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
var result = http.post('/files', e.target.result);
result.success(function () {
alert('done'):
});
}
My route looks like:
app.post('/files', function (req, res) {
var cws = fs.createWriteStream(__dirname + '/media/file');
req.pipe(cws);
res.send('success');
});
When I open /media/file with an image app I get a warning that it cannot read it. When I open the image file with a text-editor I see the base64 encoded string inside. Do I need to convert the string first before writing it to desk?
The problem was that a DataURL is prepended by meta data. You first need to remove that part before you create a base64 buffer.
var data_url = req.body.file;
var matches = data_url.match(/^data:.+\/(.+);base64,(.*)$/);
var ext = matches[1];
var base64_data = matches[2];
var buffer = new Buffer(base64_data, 'base64');
fs.writeFile(__dirname + '/media/file', buffer, function (err) {
res.send('success');
});
Got most code from this question.
In a Google chrome extension I am working on, a file is downloaded from a server with an XMLHttpRequest. This file contains some binary data which are stored in an ArrayBuffer object. In order to provide the possibility to download this file I am using the createObjectURL API.
function publish(data) {
if (!window.BlobBuilder && window.WebKitBlobBuilder) {
window.BlobBuilder = window.WebKitBlobBuilder;
}
var builder = new BlobBuilder();
builder.append(data);
var blob = builder.getBlob();
var url = window.webkitURL.createObjectURL(blob);
$("#output").append($("<a/>").attr({href: url}).append("Download"));
}
It is working fine; except that the filename is an opaque UUID like 9a8f6a0f-dd0c-4715-85dc-7379db9ce142. Is there any way to force this filename to something more user-friendly?
you can force an arbitrary filename by setting the "download" attribute of your anchor
see: http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download
I have never tried it before, but it should be possible to create a new File object (which allows you to specify a file name) and write your blob to it. Something along the lines of:
function publish(data, filename) {
if (!window.BlobBuilder && window.WebKitBlobBuilder) {
window.BlobBuilder = window.WebKitBlobBuilder;
}
fs.root.getFile(filename, {
create: true
}, function (fileEntry) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function (e) {
console.log('Write completed.');
};
fileWriter.onerror = function (e) {
console.log('Write failed: ' + e.toString());
};
var builder = new BlobBuilder();
builder.append(data);
var blob = builder.getBlob();
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
}
I think this could work for you.