Ошибка 405 Method Not Allowed: что значит и как исправить

Advertisement
Что такое ошибка 405 Method Not Allowed?
405 Method Not Allowed — код состояния HTTP, который означает, что сервер знает запрошенный адрес, но не разрешает метод, использованный в запросе. RFC 9110 (раздел 15.5.6) определяет его так: метод «известен исходному серверу, но не поддерживается целевым ресурсом».
У каждого HTTP-запроса есть метод: GET — чтобы прочитать страницу, POST — чтобы отправить форму или что-то создать, PUT и PATCH — чтобы обновить, DELETE — чтобы удалить, OPTIONS — чтобы узнать, что разрешено. Ошибка 405 означает, что URL существует, но не для этого метода. Если бы такого URL не было вовсе, вы получили бы 404.
Поскольку ошибка связана с тем, как был сделан запрос, а не с отсутствующей страницей, исправлять 405 почти всегда должен разработчик сайта. Посетители обычно сталкиваются с ней после отправки формы или перехода по устаревшей ссылке.
Как выглядит ошибка 405
| Сервер / фреймворк | Типичное сообщение |
|---|---|
| nginx | 405 Not Allowed (и строка nginx под ним) |
| Apache | Method Not Allowed. The requested method POST is not allowed for this URL. |
| IIS | HTTP Error 405.0 - Method Not Allowed. The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used. |
| Next.js / API | Пустой ответ или JSON со статусом 405, который часто виден только в DevTools |
| Консоль браузера (CORS) | Ошибка CORS, потому что предварительный запрос OPTIONS получил 405 |
Advertisement
Шаг 1: прочитайте заголовок Allow
Спросите у сервера, какие методы он принимает для этого URL. Отправьте запрос OPTIONS или повторите неудачный запрос с выводом заголовков:
# Какие методы принимает этот URL?
curl -i -X OPTIONS https://example.com/api/contact
# Повторите неудачный запрос и посмотрите на статус и заголовок Allow
curl -i -X POST https://example.com/api/contact -d 'name=test'
# HTTP/2 405
# allow: GET, HEADИнструмент HTTP Headers от DNS Robot показывает код состояния и заголовки, которые URL возвращает на обычный GET-запрос, — это удобно, когда вы проверяете страницу в браузере, а не API.
Не каждый сервер соблюдает это правило. Например, встроенная страница 405 в nginx отправляется без заголовка Allow, поэтому в nginx придётся выяснить, какой блок location обрабатывает URL (решение 2).
Если вы посетитель сайта
Вернитесь назад и обновите страницу, затем снова отправьте форму. Форма, загруженная из старой копии в кеше, может отправлять данные на адрес, который с тех пор изменился.
Не обновляйте страницу после отправки формы. Обновление страницы, которая открылась в результате отправки формы, может повторно отправить POST на URL, принимающий только GET.
Проверьте адрес на опечатки или откройте главную страницу сайта и перейдите на нужную страницу заново.
Сообщите о проблеме. Если форма на сайте не срабатывает никогда, исправить это должен владелец сайта, поэтому отправьте ему адрес страницы.
Advertisement
Решение 1: отправляйте правильный метод на правильный URL
Самая частая причина в коде — простое несоответствие: форма или вызов fetch() использует POST, а эндпоинт принимает только GET, или запрос уходит на URL страницы вместо URL API. Сравните метод в коде с заголовком Allow и документацией API.
// Эндпоинт принимает только POST, поэтому GET (метод fetch по умолчанию) вернёт 405
const res = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Ana" }),
})
if (res.status === 405) console.log("Allowed:", res.headers.get("allow"))Решение 2: nginx возвращает 405 на POST к статическим файлам
Обработчик статических файлов в nginx обслуживает только GET и HEAD. POST к файлу .html или к location, который отдаёт файлы, а не передаёт запрос вашему приложению, получает 405 Not Allowed. Так часто бывает, когда action формы указывает на статическую страницу или когда блок location, предназначенный для приложения, не срабатывает.
Настоящее решение — отправить POST в приложение (PHP, Node, Python) через proxy_pass или fastcgi_pass в нужном блоке location. Проверьте, какой блок обрабатывает URL:
# Отправка форм должна попадать в приложение, а не в обработчик статических файлов
location /api/ {
proxy_pass http://127.0.0.1:3000;
}
# После изменений проверьте конфигурацию и перезагрузите nginx
# sudo nginx -t && sudo systemctl reload nginxAdvertisement
Решение 3: IIS блокирует PUT и DELETE (WebDAV)
На серверах Windows с IIS модуль WebDAV перехватывает методы PUT и DELETE, поэтому REST API (ASP.NET Web API и другие) отвечают на них HTTP Error 405.0. Если вы не используете WebDAV, отключите его для своего сайта в web.config:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
</system.webServer>Также проверьте настройки Request Filtering (фильтрация запросов) сайта в IIS Manager, вкладка HTTP Verbs: они могут напрямую запрещать отдельные методы (такие случаи IIS отмечает как 404.6, а не 405).
Решение 4: добавьте метод в обработчик маршрута
Фреймворки возвращают 405, когда маршрут существует, но обработчика для использованного метода у него нет:
Next.js (App Router):
route.tsотвечает только на те методы, которые экспортирует. Если он экспортируетGET, но неPOST, запрос POST вернёт 405. Добавьтеexport async function POST(request: Request) { … }.Flask: по умолчанию маршруты принимают только GET. Используйте
@app.route("/contact", methods=["GET", "POST"]).Django: представления на основе классов возвращают 405 для методов без соответствующего обработчика (добавьте метод
post()), и декораторrequire_http_methodsделает то же самое.Express: по умолчанию запрос с неподходящим методом проваливается в 404, а не в 405. Если ваш API должен возвращать 405, добавьте общий обработчик, который выставляет заголовок
Allow.
Advertisement
Решение 5: обрабатывайте предварительные запросы CORS (OPTIONS)
Когда веб-страница обращается к API на другом домене с JSON или нестандартными заголовками, браузер сначала отправляет предварительный запрос OPTIONS (preflight). Если API отвечает на этот OPTIONS кодом 405, браузер сообщает об ошибке CORS и вообще не отправляет настоящий запрос, хотя сам эндпоинт сработал бы.
Настройте API так, чтобы на OPTIONS для этих маршрутов он отвечал 204 или 200 с правильными заголовками Access-Control-Allow-Methods и Access-Control-Allow-Headers. В большинстве фреймворков для этого есть готовое CORS-middleware. Например, собственный DNS Lookup API от DNS Robot отвечает на preflight кодом 204 с заголовками CORS, поэтому браузеры могут обращаться к нему с любого сайта.
405 и 400, 403, 404, 501: в чём разница
| Код | Значение |
|---|---|
| 405 Method Not Allowed | URL существует, но не для этого метода |
| 400 Bad Request | Сам запрос составлен неправильно |
| 403 Forbidden | Сервер понял запрос, но не разрешает доступ |
| 404 Not Found | По этому URL ничего нет |
| 501 Not Implemented | Сервер не поддерживает этот метод ни для одного URL |
Связанные руководства: 400 Bad Request, 403 Forbidden и 401 Unauthorized.
Проверьте, что возвращает URL
HTTP Headers Checker от DNS Robot показывает код состояния и заголовки ответа для любого URL, чтобы вы могли подтвердить ошибку 405 и увидеть, какое ПО работает на сервере.
Попробовать HTTP Headers CheckerAdvertisement
Часто задаваемые вопросы
Это значит, что сервер узнаёт URL, но не принимает использованный HTTP-метод, например POST, отправленный на страницу, которая разрешает только GET. Ответ должен содержать заголовок Allow со списком методов, которые этот URL принимает.