data:URIを使用するときに推奨されるファイル名を指定する方法はありますか?


225

たとえば、リンクをたどる場合:

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

ブラウザは、ハイパーリンク自体にbase64として保持されているデータで構成されるファイルをダウンロードするように求めます。マークアップでデフォルト名を提案する方法はありますか?そうでない場合、JavaScriptソリューションはありますか?


この問題とは無関係かもしれませんが、サーバーまたは古いブラウザの障害でない場合は、blobの&URL.createObjectURLを使用することをお勧めします
Endless

3
:一部のブラウザではMEDIATYPEのオプションのパラメータ「名前」をサポートdata:application/pdf;name=document.pdf;base64,BASE64_DATA_ENCODED
MEMS

Firefox pdf.jsに問題がありました。データuriからファイル名を抽出できない場合、場合によってはハングする傾向があります。stackoverflow.com/questions/45585921/…を
Bernhard

@mems「name」パラメータをサポートしているブラウザは?参考資料を教えてもらえますか?(私のgoogle-fuで失敗しました)。
TheAddonDepot 2018

@DimuDesignsその時点で少なくともFirefox。それはもはやそうではないように見えます。これは、MIME Con​​tent-Type(!= Content-Disposition)の "name"パラメータ(RFCにはない?)に関連しています
mems

回答:


158

次のdownload属性を使用します。

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

html5-demos.appspot.com / ...でのライブサンプル。

現在、 Chrome、Firefox、Edge、Opera、デスクトップSafariで動作しますが、iOS SafariまたはIE11では動作しません。


3
@BioDesign:Chromeのdata:URIでも機能します。参照:jsfiddle.net/pYpqW
センスフル

6
しかし、あなたはそれを行うことはできませんwindow.location.replace。たとえば、data:uriまたはによって生成されたdata:uriを作成し、window.URL.createObjectURLそれをファイルとしてダウンロードする場合は、<a>を作成してクリックする必要があります。jsfiddle.net / flyingsheep / wpQtH(いいえ、$(...).click()機能しません)
空飛ぶ羊

1
すべてのブラウザがChromeのような場合のみ... [ため息]
街灯

6
@flyingsheep $('<a href="data:text/plain,Test" download="test.txt">')[0].click()はここで正常に動作するようです(Chrome 23)(注:jQueryのメソッドではなく、ネイティブclickメソッド使用しました)。デモ:jsfiddle.net/2zsRW
Rob W

1
@flyingsheepは、Firefoxで同一生成元ポリシーを実施しているようです。「Firefox 20では、この属性は、同一生成元を持つリソースへのリンクに対してのみ有効です。」developer.mozilla.org/en-US/docs/Web/HTML/Element/a私のテストでは、Chromeにこの制限はありません。
William Denniss 2013

62

最近のChromeでは、これが非常に簡単になっています。

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

クローム30に最初の試行で働いていたすべてのこれらの他の回答はこれについて話している何IDK
マイケル・J・カルキンズ

2
今はそうですが、必ずしもそれほど簡単ではありませんでした。これらの回答の多くは数年前のものです。また、他のブラウザでも機能します。
Holf 2013年

7
ブラウザの互換性の完全なリストについては、http://caniuse.com/#feat=downloadを参照してください
tixastronauta 2014

2
@tixastronauta:そのページの情報にもかかわらず、Firefox 44では機能しません。Chromeで適切に機能します。48
ルイスA.フロリット

こんにちは@Holfは、ファイルの種類や拡張子を追加する方法、またはファイル名と同じくらい単純なファイルを追加する方法はありますか?
Fraccier 2016年

51

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属性をサポートしてません)は、デフォルト名でファイルをダウンロードする、サポートされているファイルタイプ(画像、ビデオ、オーディオファイル)の場合、新しいタブに単に表示します、…


どちらのデモもChrome 38では正常に動作します(ただし、Chrome 14以降では動作します)
fregante

より完全な解決策として、downloadjsnpmで
fregante

それは私のために動作しますが、ブラウザのページはその後更新されます。それを防ぐにはどうすればいいですか?

1
ファイルサイズが
MBを超えるとChromeでは

制限はdata:URIに属します。これは質問で言及されているものです。この回答はBlobや他のURIを持つものでも機能します
fregante

40

RFC 2397によれば、いいえ、ありません。

また、使用できる要素の属性<a>もありません。

ただし、HTML5はその後download<a>要素に属性を導入しましたが、執筆時点ではサポートは普遍的ではありません(たとえば、MSIEサポートはありません)。


9
2番目の文は執筆時点では正しかったが、もう正しくない。現在のところ、まだ広く実装されていません。
空飛ぶ羊

詳細については、このコメントを参照してください:)
空飛ぶ羊

@flyingsheep、それはされて広く実装します。
Pacerier 2015

1
私がそのコメントを書いたのは3年前ではありませんでした
空飛ぶ羊

ファイルが長
すぎる

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

私は何もないのではないかと思うので、あなたは今のところ解決策の検索をやめることができると思います:)

このスレッドで通知されているようdownloadに、html5には属性があり、Firefox 20でも機能しますhttp://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download


3
涼しい!Firefoxが存在するものに対する究極の権威であることに私は必ずしも同意しませんが。:)
Gleno

14

次の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")

1
これはFirefoxでは機能しません。以下にFx互換性のある拡張回答を追加しました。
fregante 2014

12

番号。

全体の目的は、ファイルではなくデータストリームであることです。データソースはそれをファイルとして扱うユーザーエージェントの知識を持っていてはいけません...そしてそれはしません。


6
の目的は、プロトコルベースのソースから内部データを読み取らずにdata:内部データのブロックをURL形式に変換することです。@silexの回答のリンクは、それを書き込むための優先名を提案する機能が、まだ実装されていなくても、有用であると見なされいることを示しています。
Alnitak

1
@Alnitak:便利ですか?もちろんです。技術的に適切ですか?まだ納得できません。:)
オービットでの軽さのレース

3
@Tomalakは、データの読み込みと保存の違いを考慮します-ブロブがデータにインラインでエンコードされているからといって:URLは、保存先として優先される名前が必要であることを意味しません。
アルニタク2011年

4
しかし、それが「全体の目的」であるというあなたの意見は間違っています。 data:(小さな)インラインコンテンツをファッジされたURL形式で表示できるように特別に発明されたため、個別のHTTPリクエストなしでイメージタグなどで使用できます。HTMLでは、img src属性のコンテンツはURLである必要があると記載されているため、RFC 2397が作成しました。「データソース」はありません。
Alnitak

6
@Alnitak:その通りです。データソースがありません。コンテキストはありません。URI データです。
Orbitでの軽さのレース

9

アンカー要素にダウンロード属性を追加できます。

サンプル:

<a download="abcd.cer"
    href="data:application/stream;base64,MIIDhTC......">down</a>

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

また、ディスカッションの残りのメッセージにはいくつかの情報があります。


残念ながらこれはダウンロードされません。
James Khoury、

7
この議論はデータURIフォーマットへの提案された拡張のためのものでした-それは実装されていません。
Alnitak、

実装されているかどうかにかかわらず、任意のパラメーターに対する既存のサポートがあれば、これは素晴らしいことです。
Dan Lugg、

5

Service Worker を使用すると、これが本当の意味でようやく可能になります。

  1. 偽のURLを作成します。たとえば、/ saveAs / myPrettyName.jpg
  2. URLを<a href, <img srcwindow.open(url)で使用します。これは、「実際の」URLで実行できるすべてのものです。
  3. ワーカー内でフェッチイベントをキャッチし、正しいデータで応答します。

ユーザーが新しいタブでファイルを開いてそこに保存しようとした場合でも、ブラウザーは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 );
    }
});

1
面白い!現在のところ、サポートはかなり浅いようです:caniuse.com/#feat=serviceworkers
tuomassalo

別の直接URLでファイルに「応答」する方法はありますか?
Iulian Onofrei 2016

4

私のために働いたGoogle Codeの小さな回避策スクリプトがあります:

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

データが含まれているフォームを追加して送信し、フォームを再度削除します。ハッキーですが、それは私のために仕事をしました。jQueryが必要です。

このスレッドは、Google Codeページの前にGoogleに表示されたので、ここにもリンクがあると便利だと思いました。


興味深いスクリプトですが、サーバーは応答を取得して正しく送信する必要がありますか?jsfiddle.net/hZySf
James Khoury

ファイルがどこから生成されているかわかりません。そのファイルはbase64エンコードに格納されていますか?(私はbase64に慣れていない)
街灯

@streetlight:「ファイル」(つまりデータ)はJavaScriptによって生成されます。そのプロジェクトのコンテキスト(そしておそらくほとんどの場合)では、必要なデータをJS変数に入れる何らかの方法があると想定しています。違いは、data:...URI を介してユーザーに提示する代わりに、そのスクリプトがフォームを作成してサーバーにPOSTすることです。そして、サーバーはおそらくそれをHTTP "ダウンロード"応答として直接エコーします(つまり、ファイル名を指定する適切なContent-Dispositionヘッダーを使用)。
Andrzej Doyle

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();

1
jQuery 1.11では、.remove()が原因で例外が発生します。これを回避$().appendTo()するには、変数に代入してから呼び出しますvariable.click(); variable.remove()
p0lar_bear

@ p0lar_bearでは[0]、任意の「jQuery要素」からを取得すると、それが表す最初のDOM要素が返されるため、jQueryで例外が発生するはずです。
drzaus 14

あなたは実際にすべての要素を削除/追加する必要はありません-のコメントを参照stackoverflow.com/a/17311705/1037948
drzaus

3

それは一種のハックですが、私は以前に同じ状況にありました。私はJavaScriptでテキストファイルを動的に生成していて、data-URIでエンコードしてダウンロード用に提供したいと考えていました。

これは、マイナーなメジャーユーザーの介入で可能です。リンクを生成する<a href="data:...">right-click me and select "Save Link As..." and save as "example.txt"</a>ます。先ほど述べたように、これは洗練されていませんが、専門的なソリューションが必要ない場合に機能します。

最初にフラッシュを使用して名前をクリップボードにコピーすることで、これをより簡単にすることができます。もちろん、FlashやJavaを使用させた場合(ブラウザーのサポートが減っていると思いますか?)、これを行う別の方法を見つけることができるでしょう。


これは解決策ではなく、要求された内容を満たしていません。ごめんなさい。
jcolebrand

7
笑@「マイナーなユーザー介入」。ユーザーにすべてのことをしてもらうのは「マイナーなユーザー介入」ではありません。
オービットの軽量レース、

これをstackoverflow.com/questions/17311645/…と組み合わせて、生成されたリンクをトリガーします。ユーザーの介入は必要ありません。他の多く回答で述べられているように、HTML5 download属性を指定して名前を提案できます。
drzaus 14

これはSafariの優れた回避策です。Modernizrを使用して、ダウンロード属性がサポートされていないことを検出し、リンクテキストを更新してください!
littledynamo 2016年

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という名前のファイルがダウンロード用に提供されます。トリックは、Blobの代わりにFileを使用することです。

リファレンス:https : //developer.mozilla.org/de/docs/Web/API/File


0
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 () { });
    }

1
plsはあなたの答えにさらに詳細な説明を追加します-stackoverflow.com/help/how-to-answer
Sebastian Brosch

1
この答えはごみです
ジョナサンテイラー

-2

実際には、ChromeとFireFoxでこれを実現できます。

次のURLを試してください。使用されたコードがダウンロードされます。

data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.