岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

POSTリクエストをリダイレクトしたい状況とその対応

Webアプリケーションを作成する際には,POSTのリクエストをリダイレクトして,そのまま別のURLにPOSTさせるということはできないと思っておいたほうが良さそうですね.

POSTリクエストをリダイレクトするとGETされる?POSTされる? - はこべにっき ♨

HTTP/1.1のRFC上は「できる」はずなのに、非準拠UAのせいで「できない」という話ですね。同意です。

私は現在、Webアプリケーションフレームワークの設計に関心があります。その辺にかかわる話なので、POSTリクエストをリダイレクトしたい状況にはどのようなものがあるか、また、それが「できない」場合どうしたらよいか考えてみます。

POSTリクエストをリダイレクトしたい状況

リダイレクトしたい状況は、以下の2つだけではないでしょうか。

1. POSTリクエストの処理後、別のリソースを見せたい

たとえばブックマーク登録処理後に、登録完了画面ではなく、ブックマーク一覧画面を見せたいという状況です。結構ありそうです。

2. エンドポイントのURIが移動した

REST信者の私としては、エンドポイントのURIをクライアントに知らせたくはないのですが(密結合になるため)、Twitter APIのように、仕様書で知らせざるをえないこともあるでしょう。とはいえ、そのURIをいきなり移動してはいけないと思うのですが、よんどころない事情があるとしておきます。

リダイレクトしたい状況は1と2の他にもあるのかもしれませんが、考えても浮かびませんでした。ただ、もし浮かんだとしても、私の理想とするフレームワークには無関係ではないかと思っています。

それぞれへの対応

さて、1と2についてどのように対応すべきでしょうか。

1. POSTリクエストの処理後、別のリソースを見せたい

これは「303 See Other」を使えばOKです。RFCで意図されている使い方ですし、この仕様に反するUAがあったとしても圧倒的少数でしょうから無視してかまわないと思います。

2. エンドポイントのURIが移動した

当記事の冒頭で「できない」としたのがこのケースです。RFCでは「301 Moved Permanently」「302 Found」「307 Temporary Redirect」のいずれかを使えばOKなのですが、id:hakobe932さんの調査により、非準拠のUAが多いと分かります。いずれのステータスコードを返した場合でも、Opera 9が「307 Temporary Redirect」においてダイアログを表示するように、ユーザに再POSTを促すのが正しい挙動です。

このケースでは、UAの不備のせいでリダイレクトできないわけですから、4xx系のステータスコード、具体的には「405 Method Not Allowed」なり「409 Conflict」なりを返し、レスポンスエンティティで新しいエンドポイントURIを示すのがよいのではないでしょうか。そのとき「POSTリクエストを完遂させたければ、新しいURIに再POSTせよ」という旨のメッセージも含めるべきでしょう。

Opera++

Opera 9の307時の対応は素晴らしいですね。301と302で同じようにしないのは、他の非準拠UAに合わせているからかもしれません。