使用data: URI时,有没有办法指定建议的文件名?

275
如果你举个例子,点击这个链接:
data:application/octet-stream;base64,SGVsbG8=

浏览器会提示您下载一个文件,该文件包含在超链接本身中以base64形式保存的数据。在标记中是否有一种方式可以建议一个默认名称?如果没有,是否有JavaScript解决方案?

也许与此问题无关,但我建议如果这不是服务器或旧浏览器的障碍,可以使用Blob和URL.createObjectURL。 - Endless
8
一些浏览器支持多媒体类型的可选参数 "name":data:application/pdf;name=document.pdf;base64,BASE64_DATA_ENCODED - mems
我遇到了Firefox的pdf.js问题,如果它无法从数据URI中提取文件名,则在某些情况下会出现挂起的情况。请参见https://stackoverflow.com/questions/45585921/firefox-hangs-when-displaying-a-pdf-via-data-url/45585922#45585922 - Bernhard
2
@mems 哪些浏览器支持“name”参数?你能给我指一些参考文档吗?(我的谷歌搜索失败了)。 - TheAddonDepot
1
@DimuDesigns 至少在那个时候是这样的。看起来现在不再是这种情况了。这与 MIME Content-Type (!= Content-Disposition) 的 "name" 参数有关(不在 RFC 中?) - mems
这适用于 Blob URI 吗?如何为 Blob 数据设置下载文件扩展名 - LF00
17个回答

4
有一个在Google Code上的微小的解决方案脚本对我很有用: http://code.google.com/p/download-data-uri/ 它添加了一个包含数据的表单,提交表单后再将其删除。虽然有点不靠谱,但对我来说已经足够了。需要使用jQuery。 这篇帖子在Google上出现在Google Code页面之前,我想在这里也提供链接,希望可以帮到你。

有趣的脚本,但它需要服务器获取响应并将其发送回来,对吧?http://jsfiddle.net/hZySf/ - James Khoury
我不确定文件是从哪里生成的...那个文件是否存储在base64编码中?(我对base64不太熟悉) - streetlight
@streetlight:这个“文件”(即数据)是由Javascript生成的。该项目的上下文(以及可能大多数项目)假定您有某种方式将所需数据传递到JS变量中。不同之处在于,该脚本创建一个表单将其通过POST提交到服务器,而不是通过data:... URI呈现给用户。然后服务器很可能会将其作为HTTP“下载”响应直接回显(即使用适当的Content-Disposition头指定文件名)。 - Andrzej Doyle

4
这是一个基于Holf版本的jQuery版本,可在Chrome和Firefox上运行,而他的版本似乎只能在Chrome上运行。把东西添加到body里面可能有点奇怪,但如果有更好的选择,我非常欢迎。
var exportFileName = "export-" + filename;
$('<a></a>', {
    "download": exportFileName,
    "href": "data:," + JSON.stringify(exportData, null,5),
    "id": "exportDataID"
}).appendTo("body")[0].click().remove();

1
使用jQuery 1.11时,由于.remove()方法,我遇到了一个异常。我通过将$().appendTo()分配给一个变量,然后调用variable.click(); variable.remove()来解决这个问题。 - p0lar_bear
@p0lar_bear,你应该在任何jQuery中都能得到这个异常,因为从任何“jQuery元素”中获取[0]都应该返回它所代表的第一个DOM元素,这本质上是将你从jQuery中“取出”。 - drzaus
实际上,您根本不需要添加/删除元素-请参见https://dev59.com/zWQm5IYBdhLWcg3w0RtV#17311705中的注释。 - drzaus

2

这个适用于Firefox 43.0(旧版本未经测试):

dl.js:

function download() {
  var msg="Hello world!";
  var blob = new File([msg], "hello.bin", {"type": "application/octet-stream"});

  var a = document.createElement("a");
  a.href = URL.createObjectURL(blob);

  window.location.href=a;
}

dl.html

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="utf-8"/>
    <title>Test</title>
    <script type="text/javascript" src="dl.js"></script>
</head>

<body>
<button id="create" type="button" onclick="download();">Download</button>
</body>
</html>

如果单击按钮,它会提供名为hello.bin的文件进行下载。诀窍是使用File而不是Blob
参考:https://developer.mozilla.org/de/docs/Web/API/File

1

(这个答案已经被新技术所取代,但是为了历史兴趣而保留在此处。)

有点hackish,但我以前也遇到过同样的情况。我正在使用javascript动态生成文本文件,并希望通过数据URI对其进行编码以供下载。

这可以通过小的大的用户干预来实现。生成一个链接<a href="data:...">右键单击我并选择“另存为...”,然后保存为“example.txt”</a>。正如我所说,这种方法不太优雅,但如果您不需要专业解决方案,它是有效的。

通过使用Flash将名称首先复制到剪贴板中,可以使此过程变得更加轻松。当然,如果您允许自己使用Flash或Java(现在似乎越来越少地支持浏览器?),您可能可以找到另一种方法来实现此目的。


这不是一个解决方案,也不符合要求。抱歉。 - jcolebrand
7
“Lol @“ minor user intervention”。让用户为你完成整个事情并不是“minor user intervention”。” - Lightness Races in Orbit
将此与https://dev59.com/zWQm5IYBdhLWcg3w0RtV相结合,以触发生成的链接,您不需要用户干预。 您可以指定HTML5“下载”属性,如许多 其他 答案所提到的那样,来建议一个名称。 - drzaus
这是Safari的一个很好的解决方法。使用Modernizr检测下载属性不受支持时,更新链接文本! - littledynamo

0

<a href=.. download=.. > 可以用于左键和右键 -> 另存为..,

但是 <img src=.. download=.. > 在右键 -> 另存为.. 时不起作用,建议使用 "Download.jped"。

如果将两者结合起来:<a href=.. download=..><img src=..></a>

它可以用于左键、右键 -> 另存为..,右键 -> 另存图像为..

您必须将数据URI写两次(href 和 src),因此对于大型图像文件,最好使用 JavaScript 复制 URI。

在 Chrome/Edge 88 上测试通过


-1
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
var sessionId ='\n';
var token = '\n';
var caseId = CaseIDNumber + '\n';
var url = casewebUrl+'\n';
var uri = sessionId + token + caseId + url;//data in file
var fileName = "file.i4cvf";// any file name with any extension
if (isIE)
    {
            var fileData = ['\ufeff' + uri];
            var blobObject = new Blob(fileData);
            window.navigator.msSaveOrOpenBlob(blobObject, fileName);
    }
    else //chrome
    {
        window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
         window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
            fs.root.getFile(fileName, { create: true }, function (fileEntry) { 
                fileEntry.createWriter(function (fileWriter) {
                    var fileData = ['\ufeff' + uri];
                    var blob = new Blob(fileData);
                    fileWriter.addEventListener("writeend", function () {
                        var fileUrl = fileEntry.toURL();
                        var link = document.createElement('a');
                        link.href = fileUrl;
                        link.download = fileName;
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                    }, false);
                    fileWriter.write(blob);
                }, function () { });
            }, function () { });
         }, function () { });
    }

2
请在您的回答中添加更详细的解释 - http://stackoverflow.com/help/how-to-answer - Sebastian Brosch
2
这个答案是垃圾。 - Jonathan Taylor

-2

实际上,您可以在Chrome和FireFox中实现此目标。

尝试以下网址,它将下载所使用的代码。

data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接