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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30801195/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 12:42:54  来源:igfitidea点击:

HTML anchor tag download attribute not working in Firefox for jpg and png files

javascripthtmlfirefox

提问by tejas033

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 butfor .pngand .jpgdownload tag is not working as expected i.e., download dialog or Save dialog does not appear, it directly open that image.

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

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

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

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

我已经尝试了几乎所有在 stackoverflow 上提到并由 Google 建议的解决方案。但是他们中的大多数人说“检查 firefox 版本”和其他更改,例如: 尝试在触发点击之前将元素添加到 DOM

Remove filename from download tag it is of boolean type and etc.

从下载标签中删除文件名,它是布尔类型等。

I have also tried w3schools lesson on anchor tag and download attributebut nothing seems to be working.

我也尝试过关于锚标记和下载属性的 w3schools 课程,但似乎没有任何效果。

My Mozilla Firefox version is: 38.0.5

我的 Mozilla Firefox 版本是: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.

PS:在 chrome 和 firefox 中,.docs、.xls、.pdf 文件工作正常,问题是在 firefox 中的 .png 和 .jpg。

回答by tejas033

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.

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

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.

它在 Stackoverflow 上不起作用,因此您必须在 jsFiddle 上对其进行测试。

The code does the following:

该代码执行以下操作:

  • Scans the document for a-tags.
  • Those which has data-linkset will have a common click-handler attached.
  • When clicked the link is extracted from the data-linkattribute (hrefis 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/stream
  • The Object URL is set as window.locationto redirect to this binary data which will make the browser ask user to download the file instead.
  • 扫描文档中的 a 标签。
  • 那些已data-link设置的将附加一个通用的点击处理程序。
  • 单击时,链接从data-link属性中提取(设置href为 #),通过 XHR 加载为 ArrayBuffer(适用 CORS 要求,在这种情况下不是问题),并转换为对象 URL,其中 Blob 设置为 mime-类型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();
}

Example tag:

示例标签:

<a href="#" data-link="image.jpg">Click to download</a>

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.

这也可以使用 Data-URL 来完成,但与使用 ArrayBuffer 和 blob 相比,data-url 的开销为 166%。

回答by posit labs

I had a similar problem with firefox not handling the download attribute, even for same-domain files.

我有一个类似的问题,firefox 没有处理下载属性,即使是同域文件。

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.

我的目标文件实际上托管在 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)
})

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.

在客户端,我将文件路径发送到下载端点以取回 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()
}

回答by Pradeep Singh

As you are using HTML5 attribute, each browser handling differently. So use https://github.com/dcneiner/Downloadifyfor client side forceful download instead of viewing in browser.

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

回答by tang wei

HTML5 Download Attribute doesn't work for cross origin sites. To see this enter link description here

HTML5 下载属性不适用于跨源站点。要查看此内容,请在此处输入链接描述

But we can find another way to solve this question. That is use the canvas 1. To convent the imageurl to base64 DataURL Then the image is local image

但是我们可以找到另一种方法来解决这个问题。即使用画布 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>