LoginSignup
36
29

More than 5 years have passed since last update.

JavaScriptでファイルダウンロード

Last updated at Posted at 2017-12-19

JavaScriptでファイルダウンロード

JavaScriptアドベントカレンダー 14日目です。(12/19)

リンクを押すとダウンロードが勝手に始まるやつ。

どう実装していますか? 実装する機会があり私は詰まりました。

前提として、認証のあるサーバからファイルをダウンロードする想定です。

ダウンロードが始まるやーつ

anchorタグのDOMオブジェクトを作ってあげて、urlにファイルのダウンロード先を指して、clickメソッドを呼び出してあげれば実現できます。
ただしこれは認証がcookieでやられていたなら。

 let anchor = document.createElement("a");
 anchor.href = url;
 anchor.click();

Xhrで取得してダウンロードする

認証がheaderに要素を付与して行うものだったら↑のanchor.hrefにダウンロード先をさしても認証されずに弾かれてしまいますね。
なのでxhrでheaderにトークンなりをつけて通信しましょう。
今回はfetchAPIでサンプルを書きました。

fetch("ダウンロード先", { method: 'GET', headers: new Headers([["auth-token", authToken]])}).then(response => response.blob()).then(blob => {
 let anchor = document.createElement("a");
 anchor.href = window.URL.createObjectURL(blob);
 anchor.click();
})

ポイント

  • レスポンスのbodyはBlobとして使おう
    • fetchAPIならblob()でできますね。
    • axiosや生xhr,jqueryAjaxならresponseTypeblobにしてあげましょう。オプション引数なりで渡せます

筆者がつまってたとこ

私はライブラリxhrを使ってたところ、ダウンロードしたファイルの文字コードがサーバサイドが送ってるのと別になって唸ってました。

xhr({method: "GET",
    uri: "ダウンロード先",
    headers: {
        "auth-token": authToken
    }}, (err, response, body) => {
    const blob = new Blob([ content ], { "type" : type });
    let anchor = document.createElement("a");
    anchor.href = window.URL.createObjectURL(blob);
    anchor.click();
});

それもそのはず、ブラウザ提供のxhrの仕様ではレスポンスのデータ型はコントロールすることができ、私の使っていたライブラリxhrではデフォルトでtextという指定になっており、JavaScriptの文字列として扱うようになってました。

JavaScriptの文字列に一度なったら文字コードはUTF-16になってしまいダウンロードをしても意図しない文字コードとなっていました。

そこでレスポンスをblobとして扱うようにしたところ、無駄にJavaScript文字列にならなくなったので意図した文字コードでダウンロードできましたということです。

36
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
29