在我的网络应用程序中,我支持用户上传任何类型的文档(.png,.jpg,.docx,.xls,...)。我试图为这些文档实现下载功能文档。
在Google Chrome中,如果单击“下载”链接,则会显示上述所有文档的“保存”对话框。
在Mozilla Firefox for docx和xls工作正常,保存对话框显示但表示 .png 和 .jpg 下载标签没有按预期工作,即下载对话框或保存对话框没有出现,它直接打开该图像。
我的代码:
<a href="/img/14340.jpg" download="14340.jpg">Download</a>
我已尝试过几乎所有在stackoverflow上提到并由Google建议的解决方案。但是他们中的大多数人都说要检查firefox版本&#39;和其他变化如: try adding the element to the DOM before triggering the click
从下载标签中删除文件名,它是布尔类型等等。
我也试过w3schools lesson on anchor tag and download attribute,但似乎没有任何效果。
我的Mozilla Firefox版本是:38.0.5
P.S。:在chrome以及firefox .docs,.xls,.pdf文件中运行正常,问题是firefox中的.png和.jpg。
答案 0 :(得分:4)
Firefox将使用默认处理来处理png和jpeg,这是在文档中内联它们。单击链接时,即使定义了下载属性,似乎也会让Firefox认为它有一个新图像,忽略了它的下载方面。这可能是一个暂时的错误。
这是一种方法,当然不是超级优雅,可以解决这个问题,迫使图像被解释为八位字节流。
它无法在Stackoverflow上内联工作,因此您必须 test it on jsFiddle.
代码执行以下操作:
data-link
的那些将附加一个公共点击处理程序。data-link
属性中提取(href
为#),通过XHR作为ArrayBuffer加载(适用CORS要求,在这种情况下不是问题),并且转换为Object-URL,Blob设置为mime-type octet/stream
window.location
以重定向到此二进制数据,这将使浏览器要求用户下载文件。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();
}
示例代码:
<a href="#" data-link="image.jpg">Click to download</a>
缺点是您将丢失文件名中的扩展名。
使用数据URL也可以这样做,但与使用ArrayBuffer和blob相比,data-url的开销为166%。
答案 1 :(得分:0)
我也遇到了类似的问题,即使对于相同域的文件,Firefox也无法处理下载属性。
我的目标文件实际上托管在AWS上,因此它们是跨域的。我通过一个同域端点解决了这个问题,该端点下载远程文件并将其通过管道传输到客户端。
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)
})
在客户端上,我将文件路径发送到下载端点,以获取一个Blob,然后将该Blob转换为对象url。从那里开始,它是标准的下载属性内容。
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()
}
答案 2 :(得分:-4)
当您使用HTML5属性时,每个浏览器的处理方式都不同。因此,请使用https://github.com/dcneiner/Downloadify进行客户端强制下载,而不是在浏览器中查看。
答案 3 :(得分:-4)
HTML5下载属性不适用于跨源网站。 要查看此enter link description here
但我们可以找到解决这个问题的另一种方法。那就是使用画布 1.将imageurl修改为base64 DataURL 然后图像是本地图像
<a id="download" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAEiElEQVRYR82YXWgcVRTH/2d2N82K2UKrBUEamyhWUojdSXfWmkJSmu6Hpk8a7JOKJkE09akWHwRBUGhetC2CiagPajH6ItXsTBJMICFmNjtTCwmKmNYUQaip0E1pPnZ2jswmG7ub3exsM5rO65x77u+ee/73nnsIZX4B5dIecDoE5kYiPAagGkDVqpt5ALPM+BlEYyCXEg/VXylnCrJj/Gxfn2u26uE2EL9GoFpiyACPpCFMm0b6yuKCN2n5qfQu+AS3a48LZh1ATUwIM3gGTOeq53/r+7qtLV1qvpJAQVk/wuCzDPxNEE4b96X7tYaGVCnH1n8xkfC451xRhvkGATsI1DUR9g9tNLYoUNPwcOXCou8DEI4S4cRESLxgB6KYTVDRWplxBowBb2Xy9ZHm5sVCtgWBDvXr96cE/h5Ev3N6+WU1GsxsyWY/qX/CR66Kj8H8kMekp0aj/r/yfa4DsmCWBR5l4Jt4yP8WiHizIDnjmSmg6O8Q8EyFSYfyoXKAxAuJe9we+gFMw2rE/6ajIHnOpJj+HoibjRQf1lobbmV/5wAFZL0XYF885H/O8cjkr46ZpAH9S2a6GQ/729cBraqpF2aq3qmcKRVhK6cguH8iCB1Z9a1E6G0WpKA+RYRTdtUkxbQZAENqROzMTry6qEECtZSS99qYFfWd3p2c2WedUxmgQEw/TsCrasTfWGpV2f9OAVn+JFkbZaYP4xH/+QyQFNPHQNSthvd/WwhIkrXNK43QqYbEnkL+gzH9mEl8Kh4WnyTrbiJO/+jdduPBkeZmYysi1DQ87F5Y2v6H6U4fpKCSeAWmIE1E/C/YhVmJqjM5tJYCsvYpEccpENM+F4ChiYj4WTlATtsGlMTzMKmFJDlx0WRXx2Rk/2Q5kxRSVKGo2fUZGNAbYHIPSbI2Z6R4r9baMFdssKRoHWB8VOj/7RLPABFq1tkxLqsRsXYjuMCQupMMz68W0NIO0+eLRR9Zsrsay87pCNX1TVfc61uczwDdTFZWTbfVLd8tQHPsNh6NH5Gu/2dbZp3oYbHF5pYlLrIgtMeP+hNbGSErqck0eyko61+AebBc2TudQ2uytw5Gq2ZSw+KLWxkhKXswHhiarBEM1/hGV0dROQOwJfs8u/yF51wddi7Xghfiymskp9S404Mx53K90/LDyRxaV35YD8GrvtopJpyMh8Tv7OSSU0ABRXuaGN05Bdq/J6/ZA9N4/P8uYUHcqYYODFocOUW+JGufgOBVQ+JxO1HarI2kaOfBuKWGxZeyvrbuGaTo74L58IbPIIvyrnooZsN2ULm0K81GPwMzZKbancop69nDgqeXgFoXuaPjofpr+dtetNnwRN+416za9j6IW5johF31FcurFTXxGTANlt1suN2ppEy2gIWzAK4RoTu1k+Vy2jGe6xRmxkkAu0BmV1ZNxcBL9oesgdmGFRF3AVQDcIyJRwg0ZSzzLB7AjcwEf2K7u4KqGbyPmJoARAHMMPhcdfLyV440rPJXknk2makICI0M2kvAbgC+VbskA1cJ/AsYYyx4YuW29P4BGmfO2Alhem8AAAAASUVORK5CYII=" download="image.jpg">downimage</a>