この記事を三行にまとめると
CakePHPのCSVヘルパーを使っている場合のお話Safariのときだけhtmlファイルがダウンロードされる
解決するのは簡単だけど、原因は分からずじまい
CakePHPを使ってる人で、さらにCSVを作成してダウンロードするような処理を書いてる人は、CSVヘルパーっての使ってる人もいると思うんですよ。CSVヘルパーがどんなものかってのは、こちらのサイトを見てもらうとして……ちょっと古いソースですが、でもCakePHP2でも動くからダイジョーブイ。
これを使うと、例えばデータベースから取って来たデータをCSVファイルにしてダウンロードできたりするんですが、先日、これが上手く動かなくてですね……CakePHP2でも動くってたった今言ったばかりなのに動かないってどーゆーことやねんって話だけど、ソースコード自体に問題があるわけじゃあなかったのよ、結果的に。
だって、動かないのSafariのときだけだったから。
どういう現象が起きてたかっていうと、SafariでCSVの作成およびダウンロード処理を行なうと、何でかファイルの拡張子が『.html』になっちゃうの。『sample.csv.html』みたいなファイルになってダウンロードされちゃうの。ついでにインスペクタで状況を確認してみると、こんなエラーが出てるの。
Failed to load resource: フレームの読み込みが中断しました。
ChromeやFirefoxでは、問題なかった。今まで通り、普通にCSVファイルとしてダウンロードできてた。フレームの読み込みとやらが中断することもなく、それ以外のエラーもない。IEはごめん。まだ確認してない。
最初は、Safariのバージョンが上がったからかな〜って思ったんですよ。先日、MacのOSをバージョンアップしたんですけど、そのときにSafariのバージョンも7に上がったから、何かそれで不具合が出てるのかなって。でも、CakePHP1.3の方でCSVダウンロード処理を行なったら、ちゃんとCSVファイルがダウンロードできる。まあ、フレームの読み込みが中断するっていうエラーは、出てたけど。前からこのエラーは出てたのかな。そこまでは確認してなかった。
で、結論を言うと、何が原因でこうなってるのかは、ちょっと分かりませんでした。ただ、解決方法に関しては、一応分かった。
CSVヘルパーを使うとき、ビューにこんな記述をすると思います。
$rowに何が入ってるかとかはここでは置いといて、とにかくこんな感じでデータをセットして、CSVファイルを作成する。renderメソッドを使えば自動的にダウンロード処理が行なわれるようになってるので、これでダウンロード処理が行なわれるようになる。ただし先述の通り、Safariだとこのままじゃ『.html』のファイルがダウンロードされてしまう。
そこで、この一行を足す。
これで、通常通りCSVファイルがダウンロードされる。最後までページをレンダリングさせなければ大丈夫とか、何かそういうことなのかな……?
もちろん、ChromeやFirefoxでも問題なくダウンロード処理はできます。IEはごめん。まだ確認してない。
Safariのときは相変わらず、フレームが中断されましたっていうエラーは出てしまう。そこは解決できなかったけど、CSVファイルのダウンロードはできてるから、とりあえずまあいっか〜ってことで、今回はそこから背を向けてしまいました。
マジで、原因は何なんですかね? 知ってる方がこの記事を見るようなことがあれば、ぜひともご教授願いたいのですが……。
これを使うと、例えばデータベースから取って来たデータをCSVファイルにしてダウンロードできたりするんですが、先日、これが上手く動かなくてですね……CakePHP2でも動くってたった今言ったばかりなのに動かないってどーゆーことやねんって話だけど、ソースコード自体に問題があるわけじゃあなかったのよ、結果的に。
だって、動かないのSafariのときだけだったから。
どういう現象が起きてたかっていうと、SafariでCSVの作成およびダウンロード処理を行なうと、何でかファイルの拡張子が『.html』になっちゃうの。『sample.csv.html』みたいなファイルになってダウンロードされちゃうの。ついでにインスペクタで状況を確認してみると、こんなエラーが出てるの。
Failed to load resource: フレームの読み込みが中断しました。
ChromeやFirefoxでは、問題なかった。今まで通り、普通にCSVファイルとしてダウンロードできてた。フレームの読み込みとやらが中断することもなく、それ以外のエラーもない。IEはごめん。まだ確認してない。
最初は、Safariのバージョンが上がったからかな〜って思ったんですよ。先日、MacのOSをバージョンアップしたんですけど、そのときにSafariのバージョンも7に上がったから、何かそれで不具合が出てるのかなって。でも、CakePHP1.3の方でCSVダウンロード処理を行なったら、ちゃんとCSVファイルがダウンロードできる。まあ、フレームの読み込みが中断するっていうエラーは、出てたけど。前からこのエラーは出てたのかな。そこまでは確認してなかった。
で、結論を言うと、何が原因でこうなってるのかは、ちょっと分かりませんでした。ただ、解決方法に関しては、一応分かった。
CSVヘルパーを使うとき、ビューにこんな記述をすると思います。
$this->Csv->addRow($row);
echo $this->Csv->render(true, 'sjis-win', 'utf-8');
$rowに何が入ってるかとかはここでは置いといて、とにかくこんな感じでデータをセットして、CSVファイルを作成する。renderメソッドを使えば自動的にダウンロード処理が行なわれるようになってるので、これでダウンロード処理が行なわれるようになる。ただし先述の通り、Safariだとこのままじゃ『.html』のファイルがダウンロードされてしまう。
そこで、この一行を足す。
$this->Csv->addRow($row);
echo $this->Csv->render(true, 'sjis-win', 'utf-8');
exit;//この一行を足す
これで、通常通りCSVファイルがダウンロードされる。最後までページをレンダリングさせなければ大丈夫とか、何かそういうことなのかな……?
もちろん、ChromeやFirefoxでも問題なくダウンロード処理はできます。IEはごめん。まだ確認してない。
Safariのときは相変わらず、フレームが中断されましたっていうエラーは出てしまう。そこは解決できなかったけど、CSVファイルのダウンロードはできてるから、とりあえずまあいっか〜ってことで、今回はそこから背を向けてしまいました。
マジで、原因は何なんですかね? 知ってる方がこの記事を見るようなことがあれば、ぜひともご教授願いたいのですが……。
function renderHeaders() {
header("Content-type: text/csv");
header("Content-disposition:attachment;filename=".$this->filename);
}