我想创建一个<a href
链接,单击该链接会强制浏览器打开“另存为”对话框。在所有现代浏览器上,使用HTML5 download
属性都应具有这种行为。
如果目标是外部托管的图像文件,则此操作无效。 <a href
链接将导航到该图像,而不是下载它。 (使用Imgur和Tumblr上托管的图像进行了测试)
<a href="https://i.stack.imgur.com/440u9.png" download>
<img src="https://i.stack.imgur.com/440u9.png" width="200"/>
</a>
例如,如果图像是在您的服务器上本地托管的,则类似的HTML代码是有效的有效
<a href="440u9.png" download>
<img src="440u9.png" width="200"/>
</a>
另一个示例-这将在W3Schools Tryit Editor中起作用,但如果将HTML复制到另一个沙箱(如JSFiddle),则不会起作用
<a href="https://www.w3schools.com/images/myw3schoolsimage.jpg" download>
<img src="https://www.w3schools.com/images/myw3schoolsimage.jpg" width="104" height="142">
</a>
探究的可能原因:
https:
很好> http://...
链接重定向到https://...
,所以这可能是失败的原因,但是https://...
链接也不起作用< / em> 有任何解决方法吗?我已经尝试过讨论here和here的Javascript下载方法,但这些方法最终都涉及到类似于单击href
链接的浏览器操作。
Excellent in-depth discussion of download links,包括服务器上PHP中的application/force-download
设置
与StackOverflow相关的问题:Force external download url(答案似乎不正确)
答案 0 :(得分:1)
我的解决方法:将图像下载到画布,然后将画布图像下载到本地驱动器。
代码:
<canvas id="downloadCanvas"></canvas>
<script>
var strDataURI = "https://78.media.tumblr.com/33f1b72778ca7352979b0f4555f08f02/tumblr_pfega8eUyH1r68v93o1_640.jpg";
var img = new Image;
img.crossOrigin = "Anonymous";
img.src = strDataURI;
var canvas = document.getElementById('downloadCanvas');
var ctx = canvas.getContext('2d');
img.onload = function(){
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img,0,0);
var dwBtn = document.getElementById("dw0");
var dwLink = canvas.toDataURL('image/jpeg', 1.0);
download(dwLink, "image.jpeg");
};
function download(dataurl, filename) {
var a = document.createElement("a");
a.href = dataurl;
a.setAttribute("download", filename);
var b = document.createEvent("MouseEvents");
b.initEvent("click", false, true);
a.dispatchEvent(b);
return false;
}
</script>
按照OP的要求,他需要捕获的图像具有相同的扩展名。 (伪代码)
更改这些行:
var ext = ExtensionFromUrl(url);
var fileName = NameFromUrl(url);
var dwLink = canvas.toDataURL('image/'+ext, 1.0);
download(dwLink, fileName+"."+ext);
请注意:此答案不适用于GIF图像。另外,由于它们是捕获的图像,因此透明通道也会丢失!
答案 1 :(得分:0)
得出的答案是无法以我的询问方式进行。现代浏览器将跨域下载作为一项安全功能来阻止。
请参阅: Making Firefox and Chrome download image under a specific name
Force <a download /> to download image instead of opening url link to image
如果下载必须与原始文件字节相同,那么我现在可以找到的唯一解决方案是:
服务器必须首先使用httpClient请求获取目标资源,将其保存到服务器上的本地磁盘,然后提供一个<a href='tmp.jpg' download>
链接,其中包含已保存文件的URI。或者,某些服务器框架能够创建一个模拟文件访问的字节流,在这种情况下,资源可以缓存到内存中,而不是保存到磁盘中。
缺点:数据成本等于文件大小的两倍(一次一次,一次一次),往返延迟,服务器内存/文件系统的使用。提供页面之前,可能每个带有下载链接的文件都必须存储在服务器上 上(或者可以使用websocket异步完成,在用户单击下载链接后提供文件,但有延迟)。对于大文件或高使用率的服务器,这些都是严重的缺点。
在新选项卡中打开目标URL,然后让客户端切换到该选项卡,然后手动右键单击并另存为...
缺点:这正是我们要避免的事情!
我仍然想知道是否存在一些黑客手段,例如提供本地URL并让服务器将对该特定资源的请求重定向到外部站点。