課題
例えば、'/csv/download'というリンクからCSVファイルをダウンロードさせるために、以下のようなコードをコントローラに書いたとします。
def download
csv = make_csv_file
send_file csv
end
ブラウザにてリンクをクリックすると、(期待する動作は「CSVファイルがダウンロードされる」ですが)CSVファイルがブラウザで自動的に開かれ、内容が表示されてしまいます。
解決方法
リンクを'/csv/download.csv'と拡張子付きにする。
もっといい方法がありそうですが、見つけ切れませんでした。もしご存知の方がいればコメントで教えてください。(>_<)
前提
まず前提として、上記サンプルコードでは make_csv_file という関数で正常なCSVファイルへのパスを返しているものとします。
レスポンスヘッダを確認すると、
Content-Disposition: attachment; filename="hoge.csv"
Content-Transfer-Encoding: binary
Content-Type: text/csv
となっていました。
また、ブラウザの設定によってはダウンロードではなく開くのが既定の動作となる場合がありますが、そうではない状態とします。
参考リンク:Chromeでダウンロードしたファイルを自動的に開かないようにする
試したこと
application/octet-stream
send_file csv, type: "application/octet-stream"
と修正し、レスポンスヘッダが
Content-Type: application/octet-stream
となるようにしましたが、ダメでした。(自動的に開いてしまう。以下同様)
download属性
リンクにdownload属性を追加してみましたが、ダメでした。
<a href="/csv/download" download>ダウンロード</a>
参考リンク:究極のファイルダウンロード
デフォルトのMIMEタイプを指定
routes.rbに下記のように定義し、
scope :csv do
get "download", to: "csv#download", defaults: {format: :csv}
end
コントローラ側を下記のように修正しました。
def download
csv = make_csv_file
respond_to do |format|
format.csv { send_file csv }
end
end
UnknownFormatが出なかったので、意図通りcsvとして扱われているようですが、ダメでした。