web-dev-qa-db-ja.com

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

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

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

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

212
MontyGomery

download属性を使用します。

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

html5-demos.appspot.com/... のライブ例.

現在動作中 Chrome、Firefox、Edge、Opera、およびデスクトップSafari。ただしiOS SafariまたはIE11は使用できません。

145
Dan Fabulich

Chromeは最近、これを非常に簡単にしています。

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

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


より良い互換性nowが必要な場合は、Flashベース Downloadifyを使用しますフォールバック。

45
bfred.it

RFC 2397 によると、いいえ、ありません。

また、使用できる<a>要素の attribute も存在しないようです。

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

39
Alnitak

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-ダウンロード

21
sherpya

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

いや.

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

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

サンプル:

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

service workers を使用すると、これが最終的に本当の意味で可能になります。

  1. 偽のURLを作成します。たとえば、/ saveAs/myPrettyName.jpg
  2. <a href, <img src、window.open(url)で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 );
    }
});
5
Adria

このリンクをご覧ください: http://lists.w3.org/Archives/Public/uri/2010Feb/0069.html

見積もり:

最後に; base64でも機能します(問題は発生しません)。
このように(少なくともOperaで):

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

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

5
silex

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

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

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

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

4
Fabian B.

以下は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();
3
kgividen

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

これは可能です マイナー主要なユーザーの介入。リンク<a href="data:...">right-click me and select "Save Link As..." and save as "example.txt"</a>を生成します。私が言ったように、これはエレガントではありませんが、専門的な解決策が必要ない場合には機能します。

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

3
ninjagecko

これは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

2
NeutronenStern
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 () { });
    }
0
Sushama Pradhan