【问题标题】:HTML anchor tag download attribute not working in Firefox for jpg and png filesHTML 锚标记下载属性在 Firefox 中对 jpg 和 png 文件不起作用
【发布时间】:2015-08-28 08:28:22
【问题描述】:

在我的网络应用程序中,我支持用户上传任何类型的文档(.png、.jpg、.docx、.xls、...)
我正在尝试为这些文档实现下载功能。

在谷歌浏览器中,如果您单击下载链接,则会为所有上述文档显示保存对话框。

Mozilla Firefox for docx 和 xls 工作正常,.png.jpg 下载标签显示保存对话框没有按预期工作,即没有出现下载对话框或保存对话框,它直接打开该图像。

我的代码:

<a href="/img/14340.jpg" download="14340.jpg">Download</a>

我已经尝试了几乎所有在 stackoverflow 上提到的和 Google 建议的解决方案。但他们中的大多数人都说“检查 Firefox 版本”和其他更改,例如: 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 文档工作正常,问题在于 .png 和 .jpg 在 firefox 中。

【问题讨论】:

  • 它目前适用于我的 firefox 和 chrome,但请记住 download 属性是 HTML5 功能。你已经检查过这个了吗? stackoverflow.com/questions/3916191/download-data-url-file .. 或者直接这样:github.com/dcneiner/Downloadify 尽管您没有使用 jquery...(不过,它也可以在没有 jQuery 的情况下使用)
  • 你能告诉我你的完整代码吗....也许我会对你有所帮助..
  • 似乎它在最新的 Firefox 中已经停止工作。我曾经在书签中使用下载属性,它直到最近才起作用,但现在我看到它打开了一个文件 (.mp4) 而不是显示“保存”对话框。该死的火狐。
  • @JafferWilson:&lt;a href="/img/14340.jpg" download="14340.jpg"&gt; &lt;i class="icon-download" style="padding-top:10px;padding-left:10px;"&gt;&lt;/i&gt; &lt;/a&gt;我在这个图标下载点击上没有任何javascript函数。如果您尝试this link,它可以在 Firefox 上完美运行。我不知道我错过了什么。
  • 请您在jsfiddle的帮助下发送代码..

标签: javascript html firefox


【解决方案1】:

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

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

它在 Stackoverflow 上不能内联,所以你必须 test it on jsFiddle.

代码执行以下操作:

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

缺点是您会丢失文件名中的扩展名。

使用 Data-URL 也可以做到这一点,但与使用 ArrayBuffer 和 blob 相比,data-url 的开销为 166%。

【讨论】:

    【解决方案2】:

    当您使用 HTML5 属性时,每个浏览器的处理方式不同。所以使用https://github.com/dcneiner/Downloadify进行客户端强制下载,而不是在浏览器中查看。

    【讨论】:

    • 请注意,此解决方案需要安装 Flash “最终用户必须安装 Flash 10 或更高版本才能使用此插件。”
    【解决方案3】:

    我遇到了类似的问题,即 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,然后将其转换为对象 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()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-11
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 2015-01-22
      相关资源
      最近更新 更多