Laravel『Route Method Not Allowed』の原因と対処法
- 作成日 2025.12.26
- その他
Laravelの「Route Method Not Allowed」は、アクセスしたURL自体はルーティングに存在するが、送ってきたHTTPメソッド(GET/POST/PUT/PATCH/DELETE など)がそのルートで許可されていないときに発生する。例として「GETしか定義していないURLにPOSTした」「フォームはPOSTなのにルートがPUT想定」「APIはPOSTなのにブラウザからGETで叩いている」「resourceルートのどれに当たっているか勘違いしている」などが典型。まずは“どのURLに、どのメソッドで、どのルート定義がマッチしている(またはしていない)のか”を固定すると解決が速い。
- 1. エラーの出方と発生条件
- 2. まず確認:実際に送っているメソッドとURLを一致させる
- 3. 原因1:ルート定義のメソッドと、リクエストメソッドが単純に違う
- 4. 原因2:フォーム送信でPUT/PATCH/DELETEを送れていない(method spoofing不足)
- 5. 原因3:resourceルートで“どのURLがどのメソッドか”を勘違いしている
- 6. 原因4:web.php と api.php の取り違え(APIをブラウザで開く、CSRFや認証で混乱)
- 7. 原因5:ルートキャッシュが古い(変更が反映されない)
- 8. サンプル:GET画面+POST送信+PUT更新を揃える(ルートとBlade)
- 9. チェックリスト(上から順に確認する)
エラーの出方と発生条件
典型メッセージ。
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for route /posts. Supported methods: POST.
発生条件の典型:
・ルートはあるが、HTTPメソッドが違う(GET⇔POST、PUT/PATCH、DELETE)
・HTMLフォームでPUT/DELETEを送ったつもりが、実際はPOSTになっている(@method不足)
・resourceルートのURLを手打ちして、想定と違うアクションに当たっている
・web.php と api.php を取り違えている(APIをブラウザGETで叩く等)
・ルートキャッシュが古く、定義変更が反映されていない
まず確認:実際に送っているメソッドとURLを一致させる
最初に見るべきは「URL」と「HTTPメソッド」。ブラウザのDevTools(Network)で Request Method と Request URL を確認する。
CLIなら curl で再現すると切り分けが早い。
# 例:GETで叩いているか
curl -i https://example.com/posts
# 例:POSTで叩く
curl -i -X POST https://example.com/postsLaravel側では、例外メッセージに「Supported methods: …」が出るので、許容メソッドを確認できる。
原因1:ルート定義のメソッドと、リクエストメソッドが単純に違う
例:ルートはPOSTしかないのに、ブラウザでURLを開いてGETしている。
// routes/web.php
Route::post('/posts', [PostController::class, 'store']);ブラウザで /posts を開くとGETになるため落ちる。
対処:
・一覧ページなら GET /posts を用意する
・登録は POST /posts をフォーム送信で呼ぶ
// OK
Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts', [PostController::class, 'store']);
原因2:フォーム送信でPUT/PATCH/DELETEを送れていない(method spoofing不足)
HTMLフォームはGET/POSTしか送れないため、PUT/PATCH/DELETEはLaravelのmethod spoofingを使う。
発生条件:
・ルートは PUT /posts/{post} なのに、フォームがただのPOST
// routes/web.php
Route::put('/posts/{post}', [PostController::class, 'update']);
Bladeフォーム例(OK)。
<form method="POST" action="/posts/{{ $post->id }}">
@csrf
@method('PUT')
<input type="text" name="title" value="{{ $post->title }}">
<button type="submit">Update</button>
</form>DELETEも同様。
<form method="POST" action="/posts/{{ $post->id }}">
@csrf
@method('DELETE')
<button type="submit">Delete</button>
</form>原因3:resourceルートで“どのURLがどのメソッドか”を勘違いしている
Route::resource を使うと、同じ /posts にGETとPOSTが共存し、/posts/{post} にGET/PUT/DELETEが割り当てられる。URL手打ちやリンク先ミスで想定と違うメソッドになることがある。
// routes/web.php
Route::resource('posts', PostController::class);
対処:
・ルート一覧で確認する
php artisan route:list・Bladeのリンク/フォームは route() ヘルパを使ってURLを固定する
<a href="{{ route('posts.index') }}">一覧</a>
<form method="POST" action="{{ route('posts.store') }}">
@csrf
<button type="submit">作成</button>
</form>原因4:web.php と api.php の取り違え(APIをブラウザで開く、CSRFや認証で混乱)
api.php のルートは通常 /api プレフィックスが付く。
発生条件:
・/api/posts はPOST前提なのに、ブラウザで開いてGETしている
・逆にweb側URLをAPIクライアントがPOSTしているが、web側はGETしかない
対処:
・APIはAPIクライアント/JSから正しいメソッドで叩く
・WebはGET画面を用意し、POSTはフォーム送信に限定する
curlでメソッドを明示して動作確認すると混乱が減る。
curl -i -X POST https://example.com/api/posts -H "Accept: application/json"原因5:ルートキャッシュが古い(変更が反映されない)
本番で route:cache を使っていると、routesファイルを書き換えてもキャッシュを更新するまで反映されない。
発生条件:
・ルート定義をGET→POSTに変えたのに、まだ旧定義で動いている
対処:デプロイ手順でルートキャッシュを更新する。
php artisan route:clear
php artisan route:cache同様に config:cache を使っている場合は、環境差切り分けで config も確認対象になる。
サンプル:GET画面+POST送信+PUT更新を揃える(ルートとBlade)
<!-- index.blade.php(作成フォーム) -->
<form method="POST" action="{{ route('posts.store') }}">
@csrf
<input name="title" />
<button type="submit">Create</button>
</form>
<!-- updateフォーム(PUT) -->
<form method="POST" action="{{ route('posts.update', $post) }}">
@csrf
@method('PUT')
<input name="title" value="{{ $post->title }}" />
<button type="submit">Update</button>
</form>
[/code]
<h3>チェックリスト(上から順に確認する)</h3>チェックリスト(上から順に確認する)
1) 実際に送っている Request Method と URL を確認したか(DevTools / curl)
2) 例外メッセージの「Supported methods: …」とルート定義が一致しているか
3) PUT/PATCH/DELETE のフォームに @method が入っているか(@csrf も)
4) resourceルートなら php artisan route:list で想定のルート名/URL/メソッドを確認したか
5) web/api のどちらのルートを叩いているか(/api プレフィックス含む)を確認したか
6) 本番で route:cache を使っているなら route:clear/route:cache を更新したか
-
前の記事
Laravel『Unexpected Eloquent Behavior』の原因と対処法 2025.12.25
-
次の記事
Laravel『Too Many Redirects(リダイレクトループ)』の原因と対処法 2026.01.01
コメントを書く