The New Download Attribute
Hopefully soon, most updated browser will implement the download attribute in hypertext links (aka: <a> tag)The quick summary is this one:
The download attribute, if present, indicates that the author intends the hyperlink to be used for downloading a resource. The attribute may have a value; the value, if any, specifies the default filename that the author recommends for use in labeling the resource in a local file system.
And this is a basic example:
click here to <a href="resource234.txt" download="license.txt" > download the license </a>
What Is Download For
Well, I am pretty sure you have read at least once in your life this kind of extra info beside a link:right click to download the content and "Save As ..."
Moreover, I am pretty sure you have created at least once in your server a page able to force a generic file download.
All these instructions and server side headers/files may disappear thanks to this new attribute, also because there's no such thing as "right button" on touch screens, neither in some newer device pointer.
If the file is meant to be download, it will ... cool?
Create Downloads On The Fly Via JavaScript
When I have read about it, I have instantly realized the potentials of this attribute combined with inline data uri scheme.Only HTML5 ?
Nope! Please note that many browsers let us already practice this technique. Some may open the file in a new blank page while some other may download directly the file as is for Chrome and the CSV example.As graceful degradation, the "right click" procedure will still do the trick.
Downlaod Canvas As Image Example
First example is a classic one: how to save a canvas snapshot as image via "click".// basic example function createDownloadLink(canvas, name) { var a = document.createElement("a"); a.download = name; a.title = "download snapshot"; a.href = canvas.toDataURL(); return a; } // some paragraph in the page document.querySelector( "p.snapshot" ).appendChild(createDownloadLink( document.querySelector("#game"), "snapshot" + (-new Date) + ".png" ));
When the user will tap/click on the link, the browser will simply start the download. No server side involved at all!
Save A Page As PDF
Thanks to this technique we may use same trick to produce a PDF file out of whatever web page.// basic example function createPDFLink(fileName) { var doc = new pdf(); // whatever content you want to download var a = document.createElement("a"); a.download = fileName; a.title = "download as PDF"; a.href = doc.output('datauri',{"fileName":name}); return a; } // some paragraph in the page document.querySelector( "p.saveaspdf" ).appendChild(createPDFLink( "document-" + document.title + ".pdf" ));
Of course if the page content changes we can replace the old link with a freshly new created one.
Save Table As CSV
Well, another classic here, the csv format out of a table. This is a basic but working example ;)<script> // really basic example function tableToCSV(table) { for (var header = table.querySelectorAll("tr th"), rows = table.querySelectorAll("tr td"), hlength = header.length, length = hlength + rows.length, result = Array(hlength), i = hlength, j; i < length; ++i ) { j = i % hlength; j || result.push("\n"); result.push(rows[j].innerHTML); ++j % hlength && result.push(","); } i = 0; while (i < hlength) { result[i] = header[i].innerHTML + ( ++i < hlength ? "," : "" ); } return result.join(""); } this.onload = function () { var a = document.body.appendChild( document.createElement("a") ); a.download = "table.csv"; a.href = "data:text/csv;base64," + btoa( tableToCSV(document.querySelector("table")) ); a.innerHTML = "download csv"; }; </script> <table> <tr> <th>name</th> <th>age</th> </tr> <tr> <td>Dan</td> <td>33</td> </tr> <tr> <td>John</td> <td>32</td> </tr> </table>
Most likely we can test already above example even if the name won't probably be the chosen one.
For safe base64 encode, compatible with UTF-8 pages, have a look at this script ( base64.encode() and base64.decode() ).
Compatibility
Different developers asked already about compatibility.
As I have said before, we need to differentiate between "download" attribute compatibility AND inline data uri link compatibility.
In the first case I don't know browsers that will force the download with the specified name yet, but I'll update this section as soon as I know someone.
In the latter case, IE9, Chrome, Firefox, Safari, Webkit based, and Opera seem to be already compatible.
The main problem/limit I have spotted in fuckn.es is the size of the data uri, in certain cases we may need a decent/fast machine otherwise we may end up killing RAM and CPU performances.
IE8 is compatible as well except IE8 has limited data uri for CSS images, as example, and I expect same limit for this technique.
Bear in mind when all browsers will be compatible, we will still have data stream limit problem, or better, really big files has to be parsed on the fly in one shot, no "download progress" possibility.
What is the browser support for the download attribute?
ReplyDeleteright now ... no idea :D
ReplyDeleteWorks for me in Chrome, which, as an extension developer is all I care about. It would be doubly awesome if there was a way to combine/batch multiple download links into a single click as well. Thus far this solution eludes me. :(
ReplyDelete@Dan, a bit of sci-fi, that would be possible simply creating a zip/tar on the fly via JavaScript and setting the inline data uri as result of this operation with mime type for zip or tar ... in few words, I would say yes, it's possible ;)
ReplyDeleteabout support ... all browsers that support inline data uri work already with right click and automatic download if mime type is not embeddable on the browser. The download attribute is not yet respected tho in these browsers.
ReplyDeleteNice, i've been wondering about this for a while. Didn't realize it was this simple.
ReplyDeleteSuch a great article which The attribute may have a value; the value, if any, specifies the default filename that the author recommends for use in labeling the resource in a local file system. In which The New Download AttributeHopefully soon, most updated browser will implement the download attribute in
ReplyDeleteMan thats so nice i was looking for this link for soooo long and when i used your code it worked! Thanks!
ReplyDeleteThanks for this... I did have to chaange:
ReplyDeleteresult.push(rows[j].innerHTML);
to:
result.push(rows[i-hlength].innerHTML);
Otherwise, the resulting download had the first row of data repeated for the length of the table, since j maxes out at the number of columns then starts over.
Anyone else notice this?