强制浏览器在单击时下载图像文件

IT技术 javascript jquery html
2021-02-04 18:44:07

我需要浏览器像单击 Excel 工作表一样下载图像文件。

有没有办法只使用客户端编程来做到这一点?

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript" src="Scripts/jquery-1.10.2.js">
        $(document).ready(function () {
            $("*").click(function () {
                $("p").hide();
            });
        });
        </script>
    </head>

    <script type="text/javascript">
        document.onclick = function (e) {
            e = e || window.event;
            var element = e.target || e.srcElement;
            if (element.innerHTML == "Image") {
                //someFunction(element.href);
                var name = element.nameProp;
                var address = element.href;
                saveImageAs1(element.nameProp, element.href);
                return false; // Prevent default action and stop event propagation
            }
            else
                return true;
        };

        function saveImageAs1(name, adress) {
            if (confirm('you wanna save this image?')) {
                window.win = open(adress);
                //response.redirect("~/testpage.html");
                setTimeout('win.document.execCommand("SaveAs")', 100);
                setTimeout('win.close()', 500);
            }
        }
    </script>

    <body>
        <form id="form1" runat="server">
            <div>
                <p>
                    <a href="http://localhost:55298/SaveImage/demo/Sample2.xlsx" target="_blank">Excel</a><br />
                    <a href="http://localhost:55298/SaveImage/demo/abc.jpg" id="abc">Image</a>
                </p>
            </div>
        </form>
    </body>
</html>

在下载 Excel 表格的情况下它应该如何工作(浏览器做什么)?

6个回答

使用 HTML5,您可以将“下载”属性添加到您的链接中。

<a href="/path/to/image.png" download>

兼容的浏览器将提示下载具有相同文件名的图像(在本例中为 image.png)。

如果您为此属性指定一个值,那么它将成为新的文件名:

<a href="/path/to/image.png" download="AwesomeImage.png">

更新:从 2018 年春季开始,这不再适用于跨域hrefs因此,如果您想<a href="https://i.imgur.com/IskAzqA.jpg" download>在 imgur.com 以外的域上创建,它将无法按预期工作。Chrome 弃用和移除公告

Richard Parnaby-King:使用 HTML 5 属性可以做到,但我需要在不使用 HTML5 或任何服务器端工具的情况下做到这一点(如果可以的话)感谢帮助者 :)
2021-03-12 18:44:07
尚未在所有浏览器中得到完全支持,但如果您不关心 IE 或 Safari,这是一个很好的解决方案。caniuse.com/#feat=下载
2021-03-13 18:44:07
谢谢,提供 HTML5 解决方案。如何仍然允许“另存为”让我在保存之前输入文件名?
2021-03-23 18:44:07
感谢您对跨域内容的提醒。你知道其他浏览器是否会做同样的事情吗?呃..我讨厌跨域。
2021-03-28 18:44:07
@ArjunChiddarwar 不,这会带来安全漏洞(想象一下有人将恶意文件直接保存到您的 Windows 文件夹中)。下载路径基于浏览器设置 - 例如默认情况下 Chrome 会下载到您的下载文件夹。
2021-04-08 18:44:07

通过将链接附加到文档,我也设法在 Chrome 和 Firefox 中实现了这一点。

var link = document.createElement('a');
link.href = 'images.jpg';
link.download = 'Download.jpg';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
最佳解决方案。避免 DOM 使用中的垃圾setTimeout( function () { link.parentNode.removeChild( link ); },10 );
2021-03-15 18:44:07
NB1:由于 CORS,这在本地不起作用。NB2:在 macOS Brave 中,这会立即保存图像。在 iOS Safari 中,这会产生一个对话框,询问您是要查看还是保存图像。如果你保存,它会进入一个只能在 iOS Safari 中访问的神秘地方(我希望它会保存到我的图像应用程序,详细信息请访问macreports.com/...)。在 iOS Brave 上,它只是打开图像。
2021-03-21 18:44:07
自从问题询问如何在 JAVASCRIPT 中进行操作以来,感谢应该是选定的答案。
2021-03-23 18:44:07
很好的解决方案,谢谢!请注意,如果您省略document.body.appendChild(link)它,它将在 Firefox 中不起作用。document.body.removeChild(link);after删除创建的元素也很好link.click()
2021-03-31 18:44:07
对于到处都有 Javascript 的网络应用程序来说,这实际上是一个非常好的解决方案。不过,仅适用于 Google Chrome(在我的测试设置中)。
2021-04-01 18:44:07

Leeroy & Richard Parnaby-King:

更新:从 2018 年春季开始,这不再适用于跨域 hrefs。因此,如果您想在 imgur.com 以外的域上创建,它将无法按预期工作。Chrome 弃用和移除公告

function forceDownload(url, fileName){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = fileName;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
    }
    xhr.send();
}
图像下载但未打开,因为它声明“图像已损坏”
2021-03-21 18:44:07

使用 Promise 和 async/await 的更现代方法:

toDataURL(url) {
    return fetch(url).then((response) => {
            return response.blob();
        }).then(blob => {
            return URL.createObjectURL(blob);
        });
}

然后

async download() {
        const a = document.createElement("a");
        a.href = await toDataURL("https://cdn1.iconfinder.com/data/icons/ninja-things-1/1772/ninja-simple-512.png");
        a.download = "myImage.png";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
}

在此处查找文档:https : //developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

如果请求的图像被 CORS 策略阻止,这将不起作用。
2021-04-09 18:44:07

2018 年春季更新

<a href="/path/to/image.jpg" download="FileName.jpg">

虽然这仍然受支持,但截至 2018 年 2 月,chrome 禁用了跨源下载的此功能,这意味着这仅在文件位于同一域名上时才有效。

在 Chrome 禁用跨域下载的新更新之后,我想出了一种下载跨域图像的解决方法。您可以将其修改为适合您需要的函数。如果需要,您可以通过更多研究获得图像 mime 类型(jpeg、png、gif 等)。也可能有一种方法可以对视频执行类似的操作。希望这对某人有帮助!

Leeroy & Richard Parnaby-King:

更新:从 2018 年春季开始,这不再适用于跨域 hrefs。因此,如果您想在 imgur.com 以外的域上创建,它将无法按预期工作。Chrome 弃用和移除公告

var image = new Image();
image.crossOrigin = "anonymous";
image.src = "https://is3-ssl.mzstatic.com/image/thumb/Music62/v4/4b/f6/a2/4bf6a267-5a59-be4f-6947-d803849c6a7d/source/200x200bb.jpg";
// get file name - you might need to modify this if your image url doesn't contain a file extension otherwise you can set the file name manually
var fileName = image.src.split(/(\\|\/)/g).pop();
image.onload = function () {
    var canvas = document.createElement('canvas');
    canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
    canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size
    canvas.getContext('2d').drawImage(this, 0, 0);
    var blob;
    // ... get as Data URI
    if (image.src.indexOf(".jpg") > -1) {
    blob = canvas.toDataURL("image/jpeg");
    } else if (image.src.indexOf(".png") > -1) {
    blob = canvas.toDataURL("image/png");
    } else if (image.src.indexOf(".gif") > -1) {
    blob = canvas.toDataURL("image/gif");
    } else {
    blob = canvas.toDataURL("image/png");
    }
    $("body").html("<b>Click image to download.</b><br><a download='" + fileName + "' href='" + blob + "'><img src='" + blob + "'/></a>");
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

看起来这段代码将图像解码为浏览器内存中的像素缓冲区,然后将其重新编码为 jpeg/png/gif,然后将其封装到 data-uri 中,然后希望将其存储在本地。如果是这样,则意味着图像文件中的所有元数据都丢失了。此外,重新编码 JPEG 会损失一些质量,并且质量/字节数比率会更差。不过,很高兴知道。感谢分享。
2021-03-26 18:44:07
它会下载图像,但对于来自 firebase 存储的我的图像,它说它被 CORS 策略阻止,但不是针对您的图像链接。
2021-04-05 18:44:07