Firefox と IE は何故か GET に化けた。何が起きた。
本当にさっぱりわけがわからないので、詳しい人教えて。
何があったの?
あるWebアプリケーションでPDF帳票を出力する (あるあるだ) 。
しかしこの帳票出力、出力のプレビュー画面で (つまりレスポンスが Content-Disposition: inline になっている) 更新をかけると謎のエラー落ちを起こす。
Spring MVC なのだが、ログによると List を直接インスタンス化しようとして事故っている。
ミッションはこの問題の解決なのだが、そもそもなぜそんな訳のわからん状態が起きているのだ?と調べてみたら余計に訳がわからなくなった。
下の表は、とりあえず手元のブラウザで出力 → F5 をやってみた結果だ。
F5 と書いてる時点で察していると思うが、私は Windows ユーザである (というかどこもかしこも Windows 使ってるせいで Linux を使いづらいんだ) 。このため、Safari はない。
Browser | Result |
---|---|
Chrome 63 | 警告後 POST |
Firefox 58 | 無警告でGET |
Internet Explorer 11 | 無警告でGET |
通常 POST したものをリロードした場合、確認メッセージを出した上で POST するものだが、これに限っては話が違うようだ。
直感的な (……?) 動作をしているのは Chrome だけで、他は無警告で GET する。
……意味がわからない。
検証方法
codepen を使ってそれっぽく POST してくれるボタンを作成し確認した。以下のような塩梅である。
https://codepen.io/anon/pen/XZaYOa
接続対象はローカルで適当にサーバおっ立ててなんとかした。
仮説1: 別画面向けの POST だと死ぬ
上述の出力は target にある固定の値をセットしていた。これのせいではなかろうか?
もちろんそんなことはなかった。
しかし、Firefox で検証したところ (めんどくさかったのでIEはほったらかしである) 重要な事がわかった。
- テキストデータを返した場合: 警告の上 POST する。
- PDF を返した場合: 無警告で GET する。
というわけでつまり、PDF の場合 GET に化けるという可能性が出てきた。
すると、もう一つ仮説が出てくる。
仮説2: Content-type? Content-Disposition?
もちろん現実問題としていじれば欲しい動作をしたとしてもいじるわけにはいかないのだが、それはそれとしてまあ、という話である。
が、やっぱり駄目だった。テキストを PDF っぽくしても GET に化けたし、Disposition を attachment にしてはそもそもプレビューされなくなってしまう。
仮説3: もしかしてプレビューできるバイナリ全般死ぬの?
検証できていない。ただ、大いに有り得るとは思う。
例えば、アドオンでプレビュー表示中は通信が全部 GET になるとか、表示中の更新はアドオン側でやるけど実装が GET だとか。
……いやいや、ほんとうにあるのかね、そんなこと。