Я могу отправлять GET-запросы в локальный Laravel API, но все POST-запросы завершаются ошибкой

#php #laravel #api #authentication #post

#php #laravel #API #аутентификация #Публикация

Вопрос:

У меня есть базовый Laravel API, который я пытаюсь настроить. Я настроил промежуточное программное обеспечение CORS и делаю запросы к API из другого (локального) домена (т.Е. aaa.host Интерфейс React отправляет запросы Axios в серверную bbb.host часть Laravel API).

Все запросы GET успешно проходят через API и возвращают ответ, но любые запросы POST, которые я пытаюсь выполнить, завершаются неудачей. Насколько я понимаю, токен CSRF требуется в Laravel только для веб-запросов, а не для запросов API. Таким образом, я не могу понять, чего мне не хватает и почему запросы POST не выполняются. Если я меняю маршрут POST на маршрут GET, он мгновенно срабатывает, поэтому тот факт, что это маршрут POST, кажется, является проблемой.

Вот пример того, как выглядит неудачный POST-запрос в консоли Chrome:

введите описание изображения здесь

Я просмотрел документы Laravel API, но я не понимаю, чего мне не хватает. У кого-нибудь есть какие-либо идеи? Кроме того, для чего это стоит, я использую Laravel 5.8.29. Спасибо.


Редактировать: вот что routes/api.php выглядит так:

 Route::middleware(['cors'])->group(function () {
    Route::post('/missing-subpath-on-purpose/item/create', 'SomeController@createItem');
});
  

Опять же, если я изменю Route::post Route::get и сделаю запрос Axios GET вместо POST, он будет работать нормально.

Комментарии:

1. Маршруты, объявленные в routes/api.php ?

2. Хорошо, какой ответ вы получаете от Postman?

3. Я полагаю, запрос ПАРАМЕТРОВ также необходим для предполетных запросов на вашем маршруте?

4. Ну, поскольку это междоменный, браузер отправит предполетный запрос, чтобы проверить, авторизованы ли вы для доступа к нему. Route::match(['OPTIONS','POST']) Помогает ли? Вам придется обрабатывать запрос options в самом промежуточном программном обеспечении CORS.

5. @nice_dev, ты попал в самую точку. Спасибо. Для проверки потребовалось некоторое тестирование, но браузер останавливал выполнение запроса, потому что тип содержимого был application/json . Это особенность браузера, поэтому Postman работал. Я изменил тип содержимого по умолчанию для запросов Axios на application/x-www-form-urlencoded , и это сработало. Большое вам спасибо.

Ответ №1:

Большое спасибо nice_dev за выявление реальной проблемы и помощь в ее решении. Оказывается, с Laravel API все было в порядке, и отправка POST-запросов к нему из Postman работала нормально.

Проблема была в самом браузере. Если вы отправляете запрос POST с типом содержимого of application/json , браузер принудительно выполнит два запроса, что вызывало всевозможные проблемы. (На данный момент я не знаю причин этого, но я уверен, что у разработчиков браузеров есть свои причины для этого.)

Тем не менее, изменив тип содержимого по умолчанию для всех запросов Axios в браузере на application/x-www-form-urlencoded , это решило мою проблему. Спасибо.


Редактировать: Поиграв с этим подробнее, я понял, что я действительно хотел делать application/json запросы, но это вызывало вышеупомянутые проблемы с CORS.

Чтобы исправить это, я создал следующее промежуточное программное обеспечение CORS в Laravel:

 <?php

    namespace AppHttpMiddleware;

    use Closure;

    class Cors {
        public function handle($request, Closure $next) {
            header('Access-Control-Allow-Headers: *');
            header('Access-Control-Allow-Methods: *');
            header('Access-Control-Allow-Origin: *');

            return $next($request);
        }
    }
  

Затем я добавил его в глобальное промежуточное Kernel.php программное обеспечение следующим образом:

 protected $middleware = [
    ..., // Other middleware here.
    AppHttpMiddlewareCors::class,
];
  

Ошибка, которую я допустил, заключается в том, что промежуточное ПО CORS не было частью глобального промежуточного ПО, а промежуточного ПО route, что вызывало проблемы.