HTML锚标签下载属性在Firefox中不适用于jpg和png文件

时间:2015-06-12 10:46:36

标签: javascript html firefox

在我的网络应用程序中,我支持用户上传任何类型的文档(.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。

4 个答案:

答案 0 :(得分:4)

Firefox将使用默认处理来处理png和jpeg,这是在文档中内联它们。单击链接时,即使定义了下载属性,似乎也会让Firefox认为它有一个新图像,忽略了它的下载方面。这可能是一个暂时的错误。

这是一种方法,当然不是超级优雅,可以解决这个问题,迫使图像被解释为八位字节流。

它无法在Stackoverflow上内联工作,因此您必须 test it on jsFiddle.

代码执行以下操作:

  • 扫描文档以获取a-tags。
  • 设置data-link的那些将附加一个公共点击处理程序。
  • 单击时,链接从data-link属性中提取(href为#),通过XHR作为ArrayBuffer加载(适用CORS要求,在这种情况下不是问题),并且转换为Object-URL,Blob设置为mime-type octet/stream
  • 对象URL设置为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>