In my web application I have supported user to upload any type of document (.png, .jpg, .docx, .xls, ... )
I\'m trying to implement download functionality for these do
Firefox will handle png and jpeg using default handling, which is to inline them in the document. When clicking a link, even if download attribute is defined, seem to make Firefox think it has a new image ignoring the download aspect of it. This may be a temporary bug.
Here is a way, admittedly not super-elegant, to get around this problem forcing the image to be interpreted as an octet-stream.
It does not work inline on Stackoverflow so you have to test it on jsFiddle.
The code does the following:
data-link set will have a common click-handler attached.data-link attribute (href is se to #), loaded as an ArrayBuffer via XHR (CORS requirements applies, not a problem in this case), and is converted to an Object-URL with the Blob set to mime-type octet/streamwindow.location to redirect to this binary data which will make the browser ask user to download the file instead.var links = document.querySelectorAll("a"), i = 0, lnk;
while(lnk = links[i++]) {
if (lnk.dataset.link.length) lnk.onclick = toBlob;
}
function toBlob(e) {
e.preventDefault();
var lnk = this, xhr = new XMLHttpRequest();
xhr.open("GET", lnk.dataset.link);
xhr.responseType = "blob";
xhr.overrideMimeType("octet/stream");
xhr.onload = function() {
if (xhr.status === 200) {
window.location = (URL || webkitURL).createObjectURL(xhr.response);
}
};
xhr.send();
}
Example tag:
Click to download
The drawback is that you'll loose the extension in the filename.
This is also possible to do using a Data-URL, but a data-url has a 166% overhead compared to using ArrayBuffer and a blob.