【Laravel】POST時、正しくルーティングしていても405エラー

プログラミング

POSTでアクセスを受けるAPIを開発してたのですが、web.phpに正しくルーティングしているにもかかわらず405エラーが発生してしまいました。

結果的に解決策はシンプルだったのですが、遠回りして無駄に1時間ぐらい調べてしまいました・・・。

今回はその解決策を備忘としてまとめておきます。

今回の解決策は、きちんとルーティングできているにもアクセスできない場合に試すとよい方法です。
そもそもルーティングが間違っている可能性が高い場合は、そちらを先に見直すことをおすすめします。
スポンサーリンク
スポンサーリンク

原因

結論から言うと、下記②のようにURL末尾に「/」を付与した状態でアクセスしていたことです。

① http://localhost:8000/test
② http://localhost:8000/test/

その理由は、いったん解決策を提示したあとで詳しく解説します。

解決策

二種類あります、どちらがいいかはのちほど。

(1) URL末尾「/」を削除してアクセスする(ように呼び出し側に書く)
(2) GETとPOSTの両方をルーティングする

原因の詳細

下記のようなweb.phpを作成したとします。

Route::POST('/test', 'TestController@index');

その場合、下記の二種類のどちらにアクセスしても正しい、と思っていました。

① http://localhost:8000/test
② http://localhost:8000/test/

しかし、①だと問題なくアクセスできるのですが、②だと今回の事象が発生してしまいます。

というのも、Laravelでは②にアクセスがあった場合、内部的には①にリダイレクトしているようなのですが、このリダイレクトのときに、GETメソッドでアクセスし直しているためらしいです。

ちなみに、下記のようにルーティング時にURL末尾に「/」を付与していても、「/」なしのほうにリダイレクトがかかるようです。

Route::POST('/test/', 'TestController@index');

どちらの解決策がいいか

ということで、再度選択肢。

(1) URL末尾「/」を削除してアクセスする
(2) GETとPOSTの両方をルーティングする

もう言うまでもないかと思いますが、基本的には(1)が正解です。

リダイレクトが内部的にかかる時点で、正規URLとなるのはリダイレクト後の「/」がないURLだからです。

ただ、すでに「/」ありのURLで顧客と合意を取ってしまっていたり、「/」ありのURLを先に告知してしまっていたりして、URL末尾「/」がない状態でアクセスさせるのが難しい状況もあるかと思います。

その場合の苦肉の策が、(2)の対応策です。

具体的には、下記のような書き方になります。

Route::POST('/test', 'TestController@index');
Route::GET ('/test', 'TestController@index');

まとめ

以上!

もし間違っている部分がありましたら、コメントで教えてもらえると助かります。

コメント

タイトルとURLをコピーしました