有没有办法在使用数据时指定建议的文件名:URI?

216 html javascript url save-as data-uri

例如,如果您点击链接:

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

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

Dan*_*ich 151

使用download属性:

<a download='FileName' href='your_url'>
Run Code Online (Sandbox Code Playgroud)

html5-demos.appspot.com/...上的实例.

目前适用于 Chrome,Firefox,Edge,Opera和桌面Safari,但不适用于iOS Safari或IE11.

  • 但你不能用`window.location.replace`做到这一点.如果你想创建一个数据:uri或由[`window.URL.createObjectURL`]生成的数据(https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/window.URL.createObjectURL),下载作为文件,你将不得不创建一个<a>并单击它:http://jsfiddle.net/flyingsheep/wpQtH/(不,`$(...).click()`不起作用) (6认同)
  • @flyingsheep` $('<a href="data:text/plain,Test" download="test.txt">')[0] .click()`似乎在这里工作正常(Chrome 23)(注意:我**使用原生的`click`方法**,而不是jQuery的方法.演示:http://jsfiddle.net/2zsRW/ (5认同)
  • 您可以在http://caniuse.com/#search=download上看到浏览器兼容性 (5认同)
  • @BioDesign:它甚至适用于数据:镀铬的URI.请参阅:http://jsfiddle.net/pYpqW/ (3认同)
  • @flyingsheep 似乎他们正在 Firefox 中执行同源策略“在 Firefox 20 中,此属性仅适用于指向同源资源的链接。” https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a 在我的测试中,Chrome 没有这个限制。 (2认同)
  • 此解决方案的问题是,如果用户单击链接,则文件 **_will_** 将被下载。如果您只想指定文件名(如果用户右键单击 + 将链接另存为...)怎么办? (2认同)

Hol*_*olf 60

Chrome现在非常简单:

function saveContent(fileContents, fileName)
{
    var link = document.createElement('a');
    link.download = fileName;
    link.href = 'data:,' + fileContents;
    link.click();
}
Run Code Online (Sandbox Code Playgroud)

  • 有关浏览器兼容性的完整列表,请参阅[http://caniuse.com/#feat=download](http://caniuse.com/#feat=download). (7认同)
  • 它现在确实如此,但并不总是那么容易.其中许多答案来自多年前.它们也适用于其他浏览器. (2认同)
  • @tixastronauta:尽管有该页面中的信息,但在我的firefox 44中无法正常工作。在Chrome中运行良好。48 (2认同)

fre*_*nte 46

仅限HTML:使用download属性:

<a download="logo.gif" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Download transparent png</a>
Run Code Online (Sandbox Code Playgroud)


仅限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');
Run Code Online (Sandbox Code Playgroud)

Chrome,Firefox和Edge 13+将使用指定的文件名.

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


如果现在需要更好的兼容性,请使用基于Flash的Downloadify作为后备.


Aln*_*tak 39

根据RFC 2397,不,没有.

有也没有出现任何属性的的<a>,你可以使用元素.

然而,HTML5随后download<a>元素上引入了属性,尽管在编写时支持不是通用的(例如,没有MSIE支持)

  • 在撰写本文时,第二句是正确的,但[不再是](http://developers.whatwg.org/links.html#downloading-resources).但截至目前,它还没有得到广泛实施. (9认同)
  • @Pacerier根据http://caniuse.com/#feat=download它仍然不是 (2认同)

she*_*pya 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
Run Code Online (Sandbox Code Playgroud)

有趣的文件,如果你想看看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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 凉!虽然我不一定同意Firefox是存在的最终权威.:) (3认同)

owe*_*ncm 14

以下Javascript代码段可在Chrome中使用链接的新"下载"属性并模拟点击.

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

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

downloadWithName("data:,Hello%2C%20World!", "helloWorld.txt")
Run Code Online (Sandbox Code Playgroud)


Lig*_*ica 12

没有.

整个目的是它是一个数据流,而不是一个文件.数据源不应该知道用户代理将其作为文件处理......而事实并非如此.

  • `data:`的目的是将一块_internal_数据捏合成URL格式,而不必从基于协议的源中读取它.@ silex的答案中的链接表明,为_write_建议一个首选名称的能力被认为是有用的,即使它还没有实现. (6认同)
  • @Alnitak:没错.没有数据源.没有背景.URI _is_数据. (5认同)
  • 但你关于它的"整个目的"的界限是错误的.`data:`是专门发明的,允许(小)_inline_内容以混合的URL格式出现,这样它就可以被像图像标签这样的东西使用,而不需要单独的HTTP请求.HTML说`img src`属性的内容必须是一个URL,这就是RFC 2397创建的内容.没有"数据源". (4认同)
  • @Tomalak考虑加载数据和保存数据之间的区别 - 只是因为blob是在数据中内联编码的:URL并不意味着它不应该有一个首选名称来保存它. (3认同)

cui*_*ing 8

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

样品:

<a download="abcd.cer"
    href="data:application/stream;base64,MIIDhTC......">down</a>
Run Code Online (Sandbox Code Playgroud)


sil*_*lex 5

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

引用:

它甚至可以工作(如同,不会引起问题);最后
像这样的base64 (至少在Opera中):

数据:文本/无格式;字符集= UTF-8;标头=内容处置%3A%20attachment%3B%20filename%3D%22with%20spaces.txt%22%0D%0AContent语言%3A%20en; base64,4oiaDQo% 3D

此外,讨论的其余信息中还有一些信息.

  • 这个讨论是针对数据URI格式的_proposed_扩展 - 它尚未实现. (7认同)

Adr*_*ria 5

使用服务工作者,这最终可能是最真实的.

  1. 创建一个假URL.例如/saveAs/myPrettyName.jpg
  2. <a href, <img srcwindow.open(url)中使用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 );
    }
});
Run Code Online (Sandbox Code Playgroud)