Generate Download Content From Data Url with Javascript and HTML 5 - javascript

I am developing a WebRTC application that transfers file over WebRTC data channel. After I successfully transfer the file as data url, I want to create a link says "Click to download" from that data url.
I have used HTML 5 <a> tag with download attribute to create that content. An examplary content as follows;
<a download="fileName" href="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,UEsDBBQABgAIAAA...sc1BLBQYAAAAAGQAZAKoGAAD9eQAAAAA=">
It worked just fine for small contents that lesser than 16MB or so, but for bigger contents, it just didn't worked and nothing happened when you click.
Then I tried to open new page with data url as follows;
// event.message.content is base 64 data url
window.open(event.message.content,'Downloading');
This solution also worked for small contents, but failed to download big contents.
How could I download big content by using Javascript(pure javascript if possible) and HTML 5? Is there any more efficent way than base64? Thanks to CBroe, now I know that base64 is not the efficent way. What would be the efficent way to do this?
Please feel free to ask for details if any missing.
Thanks,
Ugurcan
Edit: I've tried following code snippet, it worked for small content but not worked for bigger content too. It is probably same thing with the first one.
var save = document.createElement('a'),
event;
save.href = message.content;
save.target = '_blank';
save.download = message.identifier;
event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);

Following code snippet derived from this answer helped me to get Blob from base64 data uri.
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: mimeString
});
}
Then I wrote this code snippet in order to download Blob content
var blob = dataURItoBlob(message.content);
var blobUrl = URL.createObjectURL(blob);
var save = document.createElement('a'),
event;
save.href = blobUrl;
save.download = message.identifier;
event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);
Thanks for your kind help folks.

Related

Save file using JavaScript

I have the following code to create a file from Base64.
var byteCharacters =atob(content);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob = new Blob([byteArray]);
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
window.navigator.msSaveOrOpenBlob(blob, 'msSaveBlob_testFile.docx');
The problem is that when I execute the msSaveOrOpenBlob it ask the user for downloading/saving of file, what I want is to automatically save it to user c drive.
I think this can be done using ActiveX in IE but even when I used ActiveX to save docx file although it saved the file but it says file is corrupted, but for simple txt file it works fine.
var FileOpener = new ActiveXObject("Scripting.FileSystemObject");
var FilePointer = FileOpener.OpenTextFile("C:\taqi.docx", 2, true);
FilePointer.WriteLine("some text");
FilePointer.Close();
even writing simple string to docx file, give me error of invalid file. But if I open the same docx file in notepad than I can see the text.
Now my question is how can I use the blob object to create file silently. the file can be (txt,docx,ppt,pdf)
Any help will be appreciated.
Thanks
For security purpose browsers don't permit saving files on the user's computer without his permission.
Consider using localstorage to save it in the browser instead :
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Oracle Apex Canvas to blob in PNG format saved to item

I am struggling to convert my canvas URL to a blob format, specifically in PNG format. The DataURL is generating quite perfectly when I tested it without the conversion code, the problem comes in when trying to convert it to Blob. I am using an html button that triggers the JavaScript function with the ID buttonTextArea.
I need the Blob file to be linked to my APEX page item, which I use the $s('P9_IMAGE_CODE', Blob) format, which also works when I tested it using text only. Once the page is processed, that item will be sent into a blob column within my table.
Here is my code:
$("#buttonTextArea").click(function(dataURL) {
var BASE64_MARKER = ';base64,';
var canvas = document.getElementById('myCanvas');
var dataURL = canvas.toDataURL();
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = decodeURIComponent(parts[1]);
return new Blob([raw], {type: contentType});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: contentType});
document.getElementById("textArea").value = dataUrl;
$s('P9_IMAGE_CODE', Blob); --P9_IMAGE_CODE IS THE ITEM ON MY PAGE
});
I have been trying examples from :
https://github.com/blueimp/JavaScript-Canvas-to-Blob/blob/master/README.md
and
https://code.google.com/p/chromium/issues/detail?id=67587
Thank you in advance.
As Jeffrey pointed out, the javasscript "Blob" is not the same as the Oracle BLOB datatype.
The toDataURL function is already returning a base64 encoded string, so what you'd need to do is to save that string and then after submit convert it into a real blob.
Sending it to the database may be a bit of an issue since there is a limit of 32k bytes on an item's content. This means you'll likely have to send the string in chunks to the database. This is then not a VARCHAR2 (which also has a limit of 32k) but a CLOB.
As Wesley points out, there are some workarounds for that. The blog he linked to is one such example. There is also a plugin to facilitate the handling of clobs in apex.
Once you get the base64 string to the database, you'll have to convert it to a real blob. There is no built-in to quickly do this, but once again this is something several people have already solved.
A script is provided here by Tim Hall to convert a CLOB to a BLOB.
So:
In the browser, get the dataURL, which is a base64 encoded string
send it in chunks to the database, where it'll be a CLOB
after everything has been sent, convert the CLOB to a BLOB and save
it in your table

How to get correct MD5 hash after saving canvas as .png in Chrome extension?

I am trying to save image canvas to disk as .png in chrome extension with file name reflecting MD5 hash. For this I use something like this:
var img = document.createElement("img");
img.src=canvas.toDataURL("image/png");
var image_data = atob(img.src.split(',')[1]);
var arraybuffer = new ArrayBuffer(image_data.length);
var view = new Uint8Array(arraybuffer);
for (var i=0; i<image_data.length; i++) {
view[i] = image_data.charCodeAt(i);
}
var blob = new Blob([view], {type: 'image/png'});
var url = (window.webkitURL || window.URL).createObjectURL(blob);
var b = new FileReader;
b.readAsDataURL(blob);
b.onloadend = function () {
filename = SparkMD5.hash(b.result);
}
// ....some code
chrome.downloads.download ({ url, filename+'.png', saveAs: false });
The file is saved correctly, but MD5 hash that I get in code via SparkMD5 is different from the one I see in Windows after the file is saved. I cannot understand why. Experimented a bit with different approaches to saving (directly XMLHttpRequest, etc), but no luck yet. Probably I misunderstand some basic concept, as far as I am a bit of newbee to web programming.
I have also saved files via chrome.pageCapture.saveAsMHTML with the use of FileReader and in that case MD5 are equal.
What is wrong and is there a way to get equal MD5 for filename and final file while saving .png from Chrome extension?

createObjectURL does not work in ie10

I am reading a base64 encoded file from indexedDB and trying to link to it as a blob url. The code below works fine in Chrome but when I click the link in ie10 nothing happens. I can see on the properties of the link that the href is blob:66A3E18D-BAD6-44A4-A35A-75B3469E392B which seems right. Anyone see what I'm doing wrong?
Download Attachment
//convert the base64 encoded attachment string back into a binary array
var binary = atob(attachment.data);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
//create a blob from the binary array
var myBlob=new Blob([new Uint8Array(array)], {type: attachment.content_type});
//create a url hooked to the blob
downloadURL = (window.webkitURL ? webkitURL : URL).createObjectURL(myBlob);
//set the attachment link to the url
$('#attachmentLink').attr("href", downloadURL);
$("#attachmentLink").text(fileName);
Figured it out. IE10 does not want to open a blob url in a new window, as my code above is trying to do. I could only make this work when I set the blob url as the src of an img tag to display my file, which luckily is an image anyway.

Base64 encode/decode and download content generated in URL

I am generating a string through JavaScript and I need to download it to a text file with a predefined dynamic filename. This way there will be no room for error by employees.
This is obviously not possible in JavaScript due to security issues. However, from what I have read it should be possible with base64 encoding.
I managed to encode the string and open a url with the decoded data. The string has been decoded successfully in this URL. The format is as follows:
var data = 'data:text/plain;base64,'+L_EncodedData;
document.location = data;
I need to open a file dialog with the decoded data so the employees can download the content generated in this URL.
Any help?
Many thanks in advance
If you're still looking for an answer to this, check out my answer here. This is how I would adapt it for your needs.
// Convert the Base64 string back to text.
var txt = atob(data.reportBase64Bytes);
// Blob for saving.
var blob = new Blob([byteString], { type: "text/plain" });
// Tell the browser to save as report.txt.
saveAs(blob, "report.txt");
If you use this, make sure you grab the polyfills that I mention in the other post.
This block is fixed.
window.OpenWindowForBase64 = function(url, callback) {
var image = new Image();
image.src = url;
var w = window.open("");
w.document.write(image.outerHTML);
if (callback) {
callback(url);
}
}

Categories

Resources