Javascript/jQueryによるファイルのダウンロード

私は、ここで指定された非常に似た要件を持っています。

ユーザーのブラウザが $('a#someID').click(); の時に、手動でダウンロードを開始するようにしたいのです。

しかし、window.hrefメソッドは、現在のページの内容をダウンロードしようとしているファイルに置き換えてしまうので、使えません。

代わりに、新しいウィンドウ/タブでダウンロードを開きたいのです。これはどのようにして可能なのでしょうか?

ソリューション

不可視の<iframe>を使用します。


<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

ブラウザがレンダリングできるはずのファイル(HTMLやテキストファイルなど)を強制的にダウンロードさせるには、サーバー側でファイルのMIMEタイプを、application/x-please-download-meや、任意のバイナリデータに使用されるapplication/octet-streamなどの無意味な値に設定する必要があります。

新しいタブで開きたいだけであれば、ユーザーが target 属性を _blank に設定したリンクをクリックするしかありません。

**jQueryの場合:***。

$('a#someID').attr({target: '_blank', 
                    href  : 'http://localhost/directory/file.pdf'});

そのリンクがクリックされるたびに、新しいタブ/ウィンドウにファイルがダウンロードされます。

解説 (21)

2019年モダンブラウザーのアップデート

いくつかの注意点はありますが、これは私が現在推奨している方法です。

  • 比較的新しいブラウザが必要です。
  • ファイルが非常に大きい**と予想される場合は、オリジナルのアプローチ(iframeとcookie)に似た方法を取るべきでしょう。なぜなら、以下の操作のいくつかは、少なくともダウンロードされるファイルと同じ大きさのシステムメモリを消費する可能性があり、その他の興味深いCPUの副作用があるからです。
fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(resp => resp.blob())
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    // the filename you want
    a.download = 'todo-1.json';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    alert('your file has downloaded!'); // or you know, something with better UX...
  })
  .catch(() => alert('oh no!'));

2012年オリジナルのjQuery/iframe/cookieベースのアプローチ

私はjQuery File Download plugin (Demo) (GitHub)を作成しましたが、これもあなたの状況に役立つかもしれません。このプラグインはiframeとよく似た動作をしますが、私が非常に便利だと感じたいくつかのクールな機能があります。

  • セットアップがとても簡単で、美しいビジュアル(jQuery UI Dialog、ただし必須ではありません)、すべてがテストされています。

  • ユーザーは、ファイルのダウンロードを開始したのと同じページを離れることはありません。この機能は、現代のウェブアプリケーションにとって非常に重要になっています。

  • successCallbackとfailCallback関数により、ユーザーがどのような状況で見るかを明確にすることができます。

  • jQuery UIと組み合わせることで、開発者は、ファイルのダウンロードが行われていることをユーザーに伝えるモーダルを表示したり、ダウンロードが開始された後にモーダルを解除したり、エラーが発生したことをユーザーに親切に伝えたりすることができる。この例については、Demoを参照してください。ご参考になれば幸いです。

ここでは、プラグインsourceとプロミスを使った簡単なユースケースのデモをご紹介します。デモページ]2には、他にもたくさんの ' better UX'の例があります。

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });
解説 (10)

すでにjQueryを使用している場合は、それを利用してより小さなスニペットを作成することができます。 Andrew'さんの回答のjQueryバージョンです。

var $idown;  // Keep it outside of the function, so it's initialized once.
downloadURL : function(url) {
  if ($idown) {
    $idown.attr('src',url);
  } else {
    $idown = $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
  }
},
//... How to use it:
downloadURL('http://whatever.com/file.pdf');
解説 (7)