I have some data in indexeddb files, and I'd like to allow my users to download that data to import into other applications. I can use Blobs to do this easily:
var blob = new Blob(['herp!'], {type: 'application/octet-stream'});
var iframe = document.createElement("iframe");
iframe.id = "myiframe";
iframe.style.display = "none";
iframe.src = window.webkitURL.createObjectURL(blob); // needs a revokeObjectURL
$('#dlplaceholder').append(iframe);
The correct type parameter to Blob is key: if I set it to text/plain, it won't download the file. If I have the iframe a height and width and a display type of block, I can see the data in the iframe.
However, I'll want to build one file out of multiple values from my database, and each of those values can be large, and I can have a lot of entries. I can concatenate those values in the Blob constructor, but I'm worried about having so much data in memory that I blow up.
So I decided to create a file in the sandboxed system and append each value to it, and use the file instead of the blob as the argument to createObjectURL. But when I do that, it doesn't download; it behaves exactly as if I had used my Blob code with a type of text/plain. Here's the code:
var fname = 'mybadtest'; //UPDATE here's the problem: needs .bin file extension
var init_fs = function ( fs ) {
// first, write to the sandboxed file
fs.root.getFile(fname, {create: true, exclusive: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
// write to file completed. now use the file for download
fs.root.getFile(fname, {}, function(fileEntry) {
fileEntry.file(function(file) {
var iframe = document.createElement("iframe");
iframe.id = "myiframe";
iframe.style.display = "none";
iframe.src = window.webkitURL.createObjectURL(file) // needs revokeObjURL
$('#dlplaceholder').append(iframe);
}, errorHandler);
}, errorHandler);
};
var blob = new Blob(['derp!'], {type: 'application/octet-stream'});
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
};
window.webkitStorageInfo.requestQuota(PERSISTENT, mysz, function(grantedBytes) {
window.webkitRequestFileSystem(PERSISTENT, grantedBytes, init_fs, errorHandler);
}, err_function );
If I give the iframe a size and set the display to block, I can see the data I wrote to the file. So I know I got the file writing part right.
Any ideas on how I can give the file the right type so I can download it? I've been through the MDN docs, the HTML5 Rocks tuts, and Eric Bidelman's "Using the Filesystem API" book, but I don't see anything that addresses this situation. I'm using Chrome version 27.0.1453.110.
UPDATE: problem solved; see comment below.
UPDATED UPDATE: see Rob W's useful comment about an alternate approach below.
download
attribute of an anchor? Supported by Chrome and Firefox (20?). – Mccourt