405 Method Not Allowed
使い方
405 Method Not Allowed エラーが届いたとき、クライアントはリソースは存在するものの指定したメソッドが許可されていないと理解します。レスポンスの一部として、サーバーはそのリソースで現在サポートされているメソッドを列挙した Allow ヘッダーを送信します。
SEO への影響
Google のような検索エンジンは、405 ステータスを返す URL をインデックスしません。以前にインデックスされていた URL がこのステータスコードを返すようになると、検索結果から削除されます。
例
クライアントが読み取り専用のリソースに対して DELETE を試みます。サーバーは 405 Method Not Allowed で応答し、GET、HEAD、OPTIONS のみが許可されていることを示す Allow ヘッダーを含めます。
リクエスト
DELETE /policies.pdf HTTP/1.1
Host: example.com
レスポンス
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS
Content-Type: text/html
Content-Length: 157
<html>
<head>
<title>Operation Not Permitted</title>
</head>
<body>
<p>This resource is read-only and cannot be
deleted.</p>
</body>
</html>
対処方法
405 Method Not Allowed は、リソースは存在するものの、リクエストの HTTP メソッドをサポートしていないことを意味します。
レスポンスの Allow ヘッダーを確認します。サーバーは、そのリソースで許可されているすべてのメソッドを列挙したこのヘッダーを含めます。列挙されたメソッドのいずれかに切り替えます。ヘッダーは curl -I
正しいメソッドに切り替えます。よくある誤りは、読み取り専用のエンドポイントに POST を送ったり、送信用のエンドポイントに GET を送ったりすることです。API ドキュメントに記載された操作にメソッドを合わせます。フォーム送信は、method 属性が post に設定されていない限りデフォルトで GET になります。
API エンドポイントのドキュメントを検証します。REST API はリソースパスごとに特定のメソッドを定義します。パスとメソッドの組み合わせが有効であることを確認します。多くのフレームワークでは、/api/users と /api/users/ の末尾スラッシュの違いが異なるハンドラーへルーティングされ、一方はそのメソッドを受け付けるのにもう一方は受け付けないことがあります。
サーバー設定でメソッドの制限を確認します。Web サーバーのディレクティブは、location ごとに許可されるメソッドを制限します。Apache では、
<LimitExcept GET HEAD OPTIONS>
Require all denied
</LimitExcept>
nginx では、limit_except ディレクティブが同じことを実現します。
location /api {
limit_except GET POST {
deny all;
}
}
意図したメソッドを許可するよう、これらのディレクティブを調整します。
CORS プリフライトリクエストを処理します。クロスオリジンのリクエストは、実際のメソッドの前に OPTIONS プリフライトを発生させます。サーバーは、許可されたメソッドを列挙した正しい Access-Control-Allow-Methods ヘッダーとともに OPTIONS へ応答しなければなりません。CORS の設定が欠落または不完全だと、プリフライトに対して 405 が返ります。nginx では次のようにします。
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
アプリケーションフレームワークのルーティングを見直します。Web フレームワーク(Django、Rails、Express、Spring)は、明示的に宣言されたメソッドに対してのみルートを登録します。要求されたメソッドに対するルートのデコレーターやコントローラーのアクションが欠けていると 405 になります。ルート定義が意図した HTTP メソッドと一致していることを確認します。
静的ファイルサーバーによる干渉を確認します。nginx はデフォルトで静的ファイルを配信し、静的リソースへの POST リクエストを拒否します。POST をアプリケーションのバックエンドに向けたい場合は、location ブロックが静的ファイルハンドラーではなく上流のアプリケーションへリクエストをルーティングしていることを検証します。
コードリファレンス
.NET
HttpStatusCode.MethodNotAllowed
Rust
http::StatusCode::METHOD_NOT_ALLOWED
Rails
:method_not_allowed
Go
http.StatusMethodNotAllowed
Symfony
Response::HTTP_METHOD_NOT_ALLOWED
Python3.5+
http.HTTPStatus.METHOD_NOT_ALLOWED
Java
java.net.HttpURLConnection.HTTP_BAD_METHOD
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_METHOD_NOT_ALLOWED
Angular
@angular/common/http/HttpStatusCode.MethodNotAllowed