POST 後の振る舞い (2)
昨日の日記は人様の間違いを指摘しながら自分も間違っていたという、なんとも情けない状態だった。 自分の詰めの甘さを再認識したよ…。
それはそうと、「POST でデータを送った後は、ステータスコード 302 を返して GET させたほうがいい」という情報を Web で見かけた場合に、大切なのは「なぜそうなのか?」と考えることだと思う。ということで、今考えてみる。
- 質問
- 「なぜ、 POST 後は 302 を返したほうがいいのか」
- 回答
- 「F5 を押してリロードしても二重投稿にならないから」
- 質問
- 「じゃあ、なぜ 302 を返すと二重投稿にならないのか?」
- 回答
- 「リダイレクト後は POST じゃなくて GET を使うから」
- 質問
- 「じゃあ、なぜリダイレクト後は GET になるのか」
- 回答
- 「…(この辺から上手く説明できない)」
POST 先の URL はあくまでデータを受け付ける(掲示板だったら新しい投稿を受け付ける)ための URL であり、データを取得するための URL ではない。 POST 後にデータの一覧を表示させたいのだったら、そのための URL に GET メソッドで要求を出してもらうのが筋だから…と答えるかな。 そして、そのために本来使うステータスコードは 303 だけど、多くのクライアント(Webブラウザ)が 302 を 303 のように扱うので、実際には 302 が使われている…と、こんな感じ?
ちゃんと消化できていないので、参考になりそうな記述を調べてみる。
[Studying HTTP] HTTP Status Codeでは、以下のように解説されている。
例えば、「bbs.cgi という掲示板に投稿した後で、log.html というログファイルにリダイレクトさせたい」とします。こういう場合には、典型的にステータスコード 302 が使用されていました。しかし、こういう場合に 302 を使用してしまうのは、本来は不適切な使い方なのです。何故なら、bbs.cgi には投稿すべきデータを投稿するために POST メソッドを使用しますが、log.html には投稿すべきデータはなく、ただデータを回収するために GET メソッドを使用するからです。
「REST 入門(その5) 四つの動詞 -- GET, POST, PUT, DELETE」では以下のように書かれている。
POST メソッドは、その自由度の高さから、濫用される傾向にあります。実際には GET, PUT, DELETE で行えることも、POST でできてしまうのです。しかし、HTTP メソッド本来の意味を考えて POST メソッドを利用するのが正しいのは言うまでもありません。 POST を使うときの経験則として、POST をリソースの新規作成にだけ使う、というものがあります。新しいリソースを POST する、と覚えましょう。
なるほど。 こうやって「なぜ」を繰り返すことで、少しでも本質が見えてくるのかも。