248

例如,如果您点击链接:

data:application/octet-stream;base64,SGVsbG8=

浏览器将提示您下载一个文件,该文件由超链接本身中以 base64 格式保存的数据组成。有没有办法在标记中建议默认名称?如果没有,是否有 JavaScript 解决方案?

4

17 回答 17

187

使用download属性:

<a download='FileName' href='your_url'>

download属性适用于Chrome、Firefox、Edge、Opera、桌面版 Safari 10+、iOS Safari 13+,不适用于 IE11。

于 2011-08-04T14:44:32.040 回答
71

如今,Chrome 使这变得非常简单:

function saveContent(fileContents, fileName)
{
    var link = document.createElement('a');
    link.download = fileName;
    link.href = 'data:,' + fileContents;
    link.click();
}
于 2013-05-13T13:23:35.103 回答
58

仅限 HTML:使用download属性:

<a download="logo.gif" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Download transparent png</a>


仅限 Javascript:您可以使用以下代码保存任何数据 URI:

function saveAs(uri, filename) {
  var link = document.createElement('a');
  if (typeof link.download === 'string') {
    link.href = uri;
    link.download = filename;

    //Firefox requires the link to be in the body
    document.body.appendChild(link);
    
    //simulate click
    link.click();

    //remove the link when done
    document.body.removeChild(link);
  } else {
    window.open(uri);
  }
}

var file = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
saveAs(file, 'logo.gif');

Chrome、Firefox 和 Edge 13+将使用指定的文件名。

IE11、Edge 12 和 Safari 9不支持该download属性)将使用其默认名称下载文件,或者如果文件类型受支持,它们只会在新选项卡中显示它:图像、视频、音频文件,……</p>

于 2014-09-08T00:22:41.777 回答
42

根据RFC 2397,不,没有。

似乎也没有您可以使用的元素的任何属性。<a>

然而 HTML5 随后download在元素上引入了该属性<a>,尽管在撰写本文时支持并不普遍(例如,不支持 MSIE)

于 2008-11-12T13:52:33.723 回答
21

我在 netwerk/protocol/data/nsDataHandler.cpp 中查看了一些 firefox 源

数据处理程序仅解析内容/类型和字符集,并查看字符串中是否有“;base64”

rfc 没有指定文件名,至少 firefox 没有为它处理文件名,代码生成一个随机名称加上“.part”

我还检查了 Firefox 日志

[b2e140]: DOCSHELL 6e5ae00 InternalLoad data:application/octet-stream;base64,SGVsbG8=
[b2e140]: Found extension '' (filename is '', handling attachment: 0)
[b2e140]: HelperAppService::DoContent: mime 'application/octet-stream', extension ''
[b2e140]: Getting mimeinfo from type 'application/octet-stream' ext ''
[b2e140]: Extension lookup on '' found: 0x0
[b2e140]: Ext. lookup for '' found 0x0
[b2e140]: OS gave back 0x43609a0 - found: 0
[b2e140]: Searched extras (by type), rv 0x80004005
[b2e140]: MIME Info Summary: Type 'application/octet-stream', Primary Ext ''
[b2e140]: Type/Ext lookup found 0x43609a0

如果您想查看 Mozilla 源代码,有趣的文件:

data uri handler: netwerk/protocol/data/nsDataHandler.cpp
where mozilla decides the filename: uriloader/exthandler/nsExternalHelperAppService.cpp
InternalLoad string in the log: docshell/base/nsDocShell.cpp

我认为您现在可以停止搜索解决方案,因为我怀疑没有:)

正如在这个线程中注意到的 html5 具有download属性,它也适用于 firefox 20 http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download

于 2011-06-05T01:49:33.417 回答
15

以下 Javascript 代码段通过使用链接的新“下载”属性并模拟点击在 Chrome 中运行。

function downloadWithName(uri, name) {
  var link = document.createElement("a");
  link.download = name;
  link.href = uri;
  link.click();
}

以下示例显示了它的用法:

downloadWithName("data:,Hello%2C%20World!", "helloWorld.txt")
于 2013-04-05T11:19:07.527 回答
13

不。

整个目的是它是一个数据流,而不是一个文件。数据源不应该知道将其作为文件处理的用户代理......而且它没有。

于 2011-05-30T00:03:08.527 回答
10

您可以将下载属性添加到锚元素。

样本:

<a download="abcd.cer"
    href="data:application/stream;base64,MIIDhTC......">down</a>
于 2012-09-13T14:57:11.830 回答
8

使用service workers,这最终是真正意义上的可能。

  1. 创建一个虚假的 URL。例如 /saveAs/myPrettyName.jpg
  2. 使用 URL in <a href, <img src,window.open( url ),绝对可以使用“真实” URL 完成的任何事情。
  3. 在 worker 内部,捕获 fetch 事件,并使用正确的数据进行响应。

即使用户在新选项卡中打开文件并尝试将其保存在那里,浏览器现在也会建议 myPrettyName.jpg。就好像文件来自服务器一样。

// In the service worker
self.addEventListener( 'fetch', function(e)
{
    if( e.request.url.startsWith( '/blobUri/' ) )
    {
        // Logic to select correct dataUri, and return it as a Response
        e.respondWith( dataURLAsRequest );
    }
});
于 2015-01-24T10:56:59.247 回答
5

看看这个链接: http: //lists.w3.org/Archives/Public/uri/2010Feb/0069.html

引用:


它甚至可以像这样(至少在 Opera 中)在结尾处使用 ;base64 工作(如,不会导致问题):

data:text/plain;charset=utf-8;headers=Content-Disposition%3A%20attachment%3B%20filename%3D%22with%20spaces.txt%22%0D%0AContent-Language%3A%20en;base64,4oiaDQo% 3D

讨论的其余消息中也有一些信息。

于 2011-05-30T00:24:18.097 回答
4

这是一个基于 Holf 版本的 jQuery 版本,适用于 Chrome 和 Firefox,而他的版本似乎只适用于 Chrome。在身体上添加一些东西来做到这一点有点奇怪,但如果有人有更好的选择,我完全赞成。

var exportFileName = "export-" + filename;
$('<a></a>', {
    "download": exportFileName,
    "href": "data:," + JSON.stringify(exportData, null,5),
    "id": "exportDataID"
}).appendTo("body")[0].click().remove();
于 2014-02-20T17:25:31.977 回答
4

谷歌代码上有一个对我有用的小变通脚本:

http://code.google.com/p/download-data-uri/

它添加一个包含数据的表单,提交它,然后再次删除该表单。哈基,但它为我完成了工作。需要 jQuery。

该线程出现在 Google 代码页面之前的 Google 中,我认为将链接也放在此处可能会有所帮助。

于 2012-01-11T22:32:43.373 回答
2

(此答案已被新技术弃用,但出于历史兴趣将保留在这里。)

这有点骇人听闻,但我以前也遇到过同样的情况。我在 javascript 中动态生成一个文本文件,并希望通过使用 data-URI 对其进行编码来提供下载。

这可以通过较小的主要用户干预来实现。生成链接<a href="data:...">right-click me and select "Save Link As..." and save as "example.txt"</a>。正如我所说,这很不优雅,但如果您不需要专业的解决方案,它就可以工作。

这可以通过使用闪存先将名称复制到剪贴板来减轻痛苦。当然,如果您让自己使用 Flash 或 Java(我认为现在浏览器支持越来越少?),您可能会找到另一种方法来做到这一点。

于 2011-05-30T00:18:06.990 回答
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

于 2016-01-02T18:51:46.967 回答
0

<a href=.. download=.. >适用于左键单击和右键单击->将链接另存为..,

<img src=.. download=.. >不适用于右键单击 -> 将图像另存为.. ,建议使用“Download.jped”。

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

它适用于左键单击,右键单击->将链接另存为..,右键单击->将图像另存为..

您必须编写两次 data-uri(href 和 src),因此对于大图像文件,最好使用 javascript 复制 uri。

使用 Chrome/Edge 88 测试

于 2021-02-11T15:26:56.517 回答
-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 () { });
    }
于 2015-11-25T13:08:25.777 回答
-2

您实际上可以在 Chrome 和 FireFox 中实现这一点。

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

data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==
于 2016-11-26T15:33:10.010 回答