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 documents.
In Google Chrome if you click on Download link Save dialog is shown for all above documents.
In Mozilla Firefox for docx and xls works fine, Save dialog is shown but for .png and .jpg download tag is not working as expected i.e., download dialog or Save dialog does not appear, it directly open that image.
My code:
<a href="/img/14340.jpg" download="14340.jpg">Download</a>
I have tried almost all solutions mentioned on stackoverflow and suggested by Google. But most of them says that 'check firefox version' and other changes like: try adding the element to the DOM before triggering the click
Remove filename from download tag it is of boolean type and etc.
I have also tried w3schools lesson on anchor tag and download attribute but nothing seems to be working.
My Mozilla Firefox version is: 38.0.5
P.S.: in chrome as well as in firefox .docs, .xls, .pdf documents work fine, problem is for .png and .jpg in firefox.
The download attribute only works for same-originl URLs. So if the href is not the same origin as the site, it won't work. In other words, you can only download files that belongs to that website. This attribute follows the same rules outline in the same-origin policy.
Approach 1: Using Download attribute The download attribute simply uses an anchor tag to prepare the location of the file that needs to be downloaded. The name of the file can be set using the attribute value name, if not provided then the original filename will be used.
The download attribute specifies that the target (the file specified in the href attribute) will be downloaded when a user clicks on the hyperlink. The optional value of the download attribute will be the new name of the file after it is downloaded.
I had a similar problem with firefox not handling the download attribute, even for same-domain files.
My target files are actually hosted on AWS, so they are cross-domain. I got around this with a same-domain endpoint that downloads the remote file and pipes it to the client.
const express = require('express')
const {createWriteStream} = require('fs')
const downloadVideo = (url) => { return new Promise((resolve, reject) => {
const filePath = `/tmp/neat.mp4`
const ws = createWriteStream(filePath)
request(url, {}, (error, response, body) => {
if(error) { return reject(error) }
resolve(filePath)
}).pipe(ws)
})}
app.get('/api/download', async (req, res) => {
const videoPath = await downloadVideo(req.query.url)
res.sendFile(videoPath)
})
On the client, I send the file path to the download endpoint to get a blob back, which is then converted to an object url. From there, it's standard download attribute stuff.
async download(remoteFilePath){
const a = document.createElement('a')
const dlURL = `/api/download?url=${encodeURIComponent(remoteFilePath)}`
const blob = await fetch(dlURL).then(res => res.blob())
a.href = URL.createObjectURL(blob)
a.setAttribute('download', 'cool.mp4')
document.body.appendChild(a)
a.click()
a.remove()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With