Каковы причины Laravel 5.5 "MethodNotAllowedHttpException" - PullRequest
0 голосов
/ 14 ноября 2018

Прежде чем вы проголосуете за то, что я отправил другой вопрос об этой ошибке, или отметьте его как дубликат или что-то в этом роде, мой вопрос немного отличается

Это мои известные причины этой ошибки:

  • несоответствие формы и маршрута, например: форма использует POST, маршрут использует GET
  • Несовпадение токена CSRF / отсутствует: нет csrf токен в мета или в поле формы

Я проверил обе эти причины:

  • обеспечил соответствие формы и маршрута
  • попытался отключить проверку csrf, комментируя csrf промежуточное ПО проверки в app/Http/Kernel.php, но все еще получил эту ошибку (это правильный метод?)

По сути, эти два - то, что я знаю, и что я нашел при поиске здесь.

Итак, мой вопрос:

Помимо этих двух причин, есть ли другие условия, которые могут привести к этой ошибке?

Если вы хотите увидеть мой код:

* * Маршруты одна тысяча тридцать восемь / web.php
Route::post('/export', [
    'as' => 'export.csv',
    'uses' => 'ToolsController@export'
]);

HTML-форма

    <form class="form-inline" action="{{ route('export.csv') }}" id="csv_export" method="post">
        {{ csrf_field() }}
        <input type="hidden" name="type" value="site_maps">
        <input type="hidden" name="id" value="{{ request('id') }}">
        <button type="submit" class="btn btn-primary">Export to CSV</button>
    </form>

приложение / Http / Контроллеры / ToolsController.php

namespace App\Http\Controllers;

class ToolsController extends Controller
{
    public function export(Request $request)
    {
         // some function
    }
}

Дополнительные детали:

Существует набор файлов cookie XSRF-TOKEN, попытался удалить его в браузере, но он снова появляется.

обновление

заголовок запроса

POST /export HTTP/1.1
Host: somehost.com
Connection: keep-alive
Content-Length: 68
Pragma: no-cache
Cache-Control: no-cache
Origin: http://somehost.com
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Save-Data: on
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://somehost.com/map/47
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,id-ID;q=0.8,id;q=0.7
Cookie: sso_token_33=--some-key--; XSRF-TOKEN=--some-token--; somehost_session=--some-cookie--

данные формы

_token=--some-other-token--&type=site_maps&id=47

нет группировки маршрутов

обновление

У меня странный случай, как вы можете видеть на рисунке ниже, браузер правильно отправляет запрос POST, но Laravel, похоже, видит его как запрос GET, Есть ли какие-либо настройки Apache, которые могут вызвать такое поведение?

post vs get

список маршрутов:

+--------+----------+----------------+----------------+-------------------------------------------------+--------------+
| Domain | Method   | URI            | Name           | Action                                          | Middleware   |
+--------+----------+----------------+----------------+-------------------------------------------------+--------------+
|        | POST     | export         | export.csv     | App\Http\Controllers\ToolsController@export     | web          |
|        | GET|HEAD | map/{id}       | pages.show     | App\Http\Controllers\PagesController@show       | web          |
|        | GET|HEAD | tree           | pages.tree     | App\Http\Controllers\PagesController@tree       | web          |
+--------+----------+----------------+----------------+-------------------------------------------------+--------------+

1 Ответ

0 голосов
/ 14 ноября 2018

MethodNotAllowedHttpException - это только , выбрасываемое, когда метод не соответствует определению маршрута.Это означает, что все эти условия выполняются:

  • Глагол HTTP запроса (GET, POST и т. Д.) Отсутствует в списке разрешенных методов, как определено соответствующим маршрутом
  • и a _method поле формы не было отправлено
  • и заголовок X-HTTP-Method-Override не был отправлен
  • и метод не был OPTIONS

Некоторые определения маршрутов допускают несколько методов.Например, Route::get() определяет GET и HEAD как приемлемые.

Потенциальные причины

Ошибка на самом деле ясна (в запросе использовался неправильный метод), но причина иногда более тонкая.Начиная с самого очевидного и заканчивая наименьшим, здесь приведены общие причины:

  • Отправка запроса GET на маршрут, определенный как Route::post()
  • Определение маршрута DELETE, PATCH и т. Д. Изабывая поле _method в HTML-форме
  • Запрос неправильного маршрута (опечатка, ошибка копирования / вставки) - проверьте вкладку сети инструментов разработчика и сравните заголовки запроса :path и :method со столбцами URI и Method php artisan route:list
  • При определении маршрута внутри Route::group() может быть добавлен префикс url, например api/ или admin/ - это будет видно сroute:list
  • Определение маршрутов в неправильном порядке, например, users/active необходимо определить до users/{user}, в противном случае {user} переменная маршрута будет соответствовать 'active'

Если вы все еще не видите проблему, попробуйте поиграть против пути, который вы копируете из заголовка запроса на вкладке сети ваших инструментов разработчика:

$ php artisan tinker
>>> $uri = '/your/requested/path'
>>> $method = 'POST'
>>> app('router')->getRoutes()->match(app('request')->create($uri, $method))
=> Illuminate\Routing\Route {#191
 +uri: "...",
    ...

Если все все же выглядит правильно, возможно, пора начинатьt проверка ваших конфигураций Apache / Nginx / IIS, в частности поиск ситуаций перенаправления / перезаписи, таких как добавление / удаление поддоменов (например, www) или https.

или, если это вызвало то же исключение, попробуйте без метода $и внимательно изучите ответ:

>>> app('router')->getRoutes()->match(app('request')->create($uri))

Проблема с токеном csrf не вызовет эту ошибку.Вместо этого это вызовет другое исключение, такое как TokenMismatchException, или в некоторых случаях может быть ошибка авторизации.Аналогичным образом, проблемы с файлами cookie не должны вызывать такую ​​ошибку.

Поскольку это исключение Laravel / Symfony, должно исключить проблему IIS / Apache / Nginx (если только правило перезаписи не являетсяперехватить запрос).Например, в IIS некоторые глаголы отключены по умолчанию (PUT, DELETE и т. Д.), Но вместо этого будет отображаться страница с ошибкой IIS 405. В этом случае

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...