mimeタイプに対して、クライアントがどのように振る舞うかは基本的にクライアント次第という理解なんですが、じゃあ明示的に自動生成したファイルをダウンロードさせるにはどうするのか?というのをちょっと調べたら、情報が出てきたので追試しました。
テストコードは、ArangoDBのFoxx環境用のJSです。
/download_file
が実際にファイルを生成して返すエンドポイントです。このページを叩くと、ダウンロードが始まります。mimeタイプの application/download
がポイントです。あと、ファイル名も Content-Disposition
で指定できます。
(function() {
"use strict";
var Foxx = require("org/arangodb/foxx"),
controller = new Foxx.Controller(applicationContext)
controller.get("/download_file", function(req, res) {
res.set("Content-Type", "application/download");
res.set("Content-Disposition", 'attachment; filename="test.csv"');
res.body = ['"name","age"',
'"Yoshiki","33"'].join('\n');
});
}());
ここまでは上記のリンクに出てきたんですが、よくあるダウンロードサイトとかどうなのかな、と思って、他のエンドポイントも実験で作ってみました。
controller.get("/download", function(req, res) {
res.set("Content-Type", "text/html");
res.body = '<html><body><a href="./thanks">Download</a></body></html>';
});
controller.get("/thanks", function(req, res) {
res.set("Content-Type", "text/html");
res.body = '<html><head><meta http-equiv="refresh" content="0;URL=./download_file"></head><body><a href="./download_file">Retry</a></body></html>';
});
/download
がダウロードページ相当です。まぁここは単なるリンクですので無視してもらっても大丈夫です。
/thanks
がよくある「ダウンロードありがとう、うまくできなかったらここをクリックして直接落としてね」というページです。このページにアクセスすると即座に上記のファイルダウンロードページにジャンプ、となっていますが、実際にはジャンプしません(Chrome/Firefox)。ダウンロードするものの、ページはそのままです。Retryのリンクをクリックしても、同じ挙動(ページはそのままでダウンロード開始)です。これみたいに、iframeとか、dataスキームみたいな黒魔術を使ってなんかやっているのかなぁ、とか勝手に思ってましたが、もっとシンプルでした。
追記
これを見ると、 Content-Disposition
が大事みたいですね。RFCで決まっているとのこと。こちらのサンプルを見ると、content-typeは application/download
じゃなくてもOKっぽい。Qiitaは投稿したあとに関連項目が出て理解が深まるので勉強メモをアップするにはいいですね。