Androidブラウザにphpからファイルを送る方法について
いわゆるダウンローダの挙動について。
有用なサンプルやQAはWeb上にたくさん落ちているので、あえて詳細は列挙しない。
個人的に心の支えになったのはこちらのサイト(英語)。
で、自分の場合は、ユーザー認証をセッション使ってやっていて、そのユーザーがそのファイルをダウンロードする権限を有しているかの判定をダウンローダに行わせる必要があったので、普通にダウンローダの冒頭でセッションを開始、パラメータをDBと突き合わせてダウンロードを行うように実装していた。
が、上手く動かない。
1件目はなんとか動くものの、複数件を同時にダウンロードしようとしたり、2.1などの少し古い端末だとまったくダウンロードが機能しない。
エラーが出るならまだしも、通信中に挙動が不安定になってタイムアウトするような状態になってしまい、にっちもさっちも行かなくなった。
で、色々考えた内容が以下。
- Androidブラウザは、ブラウジングするプログラムとダウンロードを行うプログラムが別になっている(apacheのログやタスク管理ツールで把握)。
- なので、ダウンロードの際にクッキーやセッションといったブラウザの機能を利用しようとするとうまく行かない(仕様なのかバグなのかは分からない)。
- つまり、ダウンロードで必要な情報はGET渡しの引数のみで制御しなければならない(例:dl.php?param=ABC123)。
結論として、
- 一旦ダウンロード前にセッション等から情報を引き出してサーバのDBに保管し、それに紐づくトークンを発行する(dl1.php?filename=abc.pdfとか)。
- ダウンローダ本体へトークンのみを引数としてリダイレクトする(dl2.php?token=31654987とか)。
- ダウンローダはDBからトークンを使用して必要な情報を引き出し、適切な判定、ストリーム処理を行う。
という構造にした。
今のところ、2.1や4.xの複数の端末で、同時2〜3件のダウンロードもスムーズに行えることを確認済み。
また、リダイレクトしてダウンロードを行う際、ブラウザとダウンローダから最低2回リクエストが飛ぶので、DBからトークンを削除するのはダウンロード完了後(or有効期限まで)としたほうがよい。
以上、もし認証やセッション機能を使っていてダウンローダが上手く機能しないよぉ・・・とお悩みの方がいたら、ヒントにしてほしい。