Добавление заголовка принятия в промежуточном программном обеспечении, чтобы маршруты API возвращали JSON при ошибке - PullRequest
0 голосов
/ 18 июня 2020

Проблема : когда кто-то отправляет почтовый запрос в мое laravel приложение по любому маршруту, начинающемуся с /api, и они НЕ указывают 'Accepts: application/json' в заголовках, он возвращает HTML если есть ошибка. Я хочу, чтобы он возвращал JSON для любого маршрута /api при любой общей c неперехваченной ошибке.

Моя первая попытка решения :

Я добавил новый класс промежуточного программного обеспечения под названием ApiAccepts, и это функция дескриптора:

    public function handle($request, Closure $next) {
        // get the courier name
        $request->headers->add(['Accept' => 'application/json']);
        return $next($request);
    }

Затем в Http\Kernel.php я настроил группу промежуточного программного обеспечения api

protected $middlewareGroups = [
        'web' => [
            ...
        ],

        'api' => [
            'throttle:5000,1',
            \App\Http\Middleware\ApiAccepts::class,
            'bindings',
        ],
    ];

Кажется, это работает иногда , но иногда нет. Проблема, похоже, в функции $request->expectsJson() - иногда она, кажется, выплевывает ложь, хотя должна быть истинной. Это связано с тем, что функция $request->getAcceptableContentTypes(), кажется, кэширует свои результаты, и иногда она явно кэширует пустой массив, но в других случаях она видит заголовок Accept, который я установил в промежуточном программном обеспечении.

[edit] при тестировании сейчас , он работает более стабильно. Я не знаю почему, и я не думаю, что могу на это положиться ... Мне бы хотелось получить отзывы, если вы считаете, что это правильное решение.

Моя вторая попытка решение :

из-за вышеуказанной проблемы я подумал, что было бы интересно попытаться переопределить функцию $request->expectsJson. Я зашел на app\Exceptions\Handler.php и добавил эти строки кода, чтобы попробовать:

if (Str::startsWith($request->path(), 'api')) {
    $request->expectsJson = function() { return true; }; // all api routes expect json by default
    $request->headers->add(['Accept' => 'application/json']);
}

Я почти уверен, что эта попытка вообще ничего не дала.

...