Ответ ошибки приходит в формате html, когда нужен json

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
De-Luxis
Сообщения: 36
Зарегистрирован: 2014.06.19, 11:16

Ответ ошибки приходит в формате html, когда нужен json

Сообщение De-Luxis »

Добрый день.
Пишу rest api через модуль, с отдельной от основного приложения авторизацией.

В bootstrap модуля для этого прописано:

Код: Выделить всё

    public function bootstrap($app): void 
    {
        if ($app instanceof \yii\web\Application) {
            $pathInfo = $app->request->pathInfo;

            if (strpos($pathInfo, 'api') !== 0) {
                return;
            }

            $app->setComponents([
                'user' => [
                    'class'           => User::class,
                    'identityClass'   => ApiUser::class,
                    'enableAutoLogin' => false,
                    'enableSession'   => false
                ]
            ]);
        }
    }
    
    public function behaviors(): array
    {
        return [
            'authenticator' => [
                'class' => HttpBasicAuth::class,
            ],
        ];
    }
Столкнулся с проблемой. Если передается неверные реквизиты доступа, то возвращается ошибка в формате html.
Хотя необходимые заголовки для указания нужного формата передаются:
Изображение

Если кинуть исключение в контроллере модуля, то ошибка приходит корректно в формате json или xml, если задать соответствующее значение у заголовка.
Последний раз редактировалось De-Luxis 2019.10.11, 10:37, всего редактировалось 1 раз.
De-Luxis
Сообщения: 36
Зарегистрирован: 2014.06.19, 11:16

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение De-Luxis »

Не хочу городить костыли в виде

Код: Выделить всё

$app->response->format = Response::FORMAT_JSON;
Может есть более тривиальные способы?
Может что-то не правильно делаю?
Usick
Сообщения: 42
Зарегистрирован: 2017.04.11, 12:07

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение Usick »

Если глобально, то через конфиг

Код: Выделить всё

'components' => [
	...
        'response' => [
            'format' => 'json',
        ],
        ...
],
De-Luxis
Сообщения: 36
Зарегистрирован: 2014.06.19, 11:16

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение De-Luxis »

Usick писал(а): 2019.10.11, 12:13 Если глобально, то через конфиг

Код: Выделить всё

'components' => [
	...
        'response' => [
            'format' => 'json',
        ],
        ...
],
Не подходит. Нужно чтоб отдавало автоматически в зависимости от заголовка.
Аватара пользователя
proctoleha
Сообщения: 298
Зарегистрирован: 2016.07.10, 19:00

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение proctoleha »

Если вы стучитесь к контроллеру в модуле, унаследованному от \yii\rest\Controller, то должно придти все нормально, например:

Код: Выделить всё

HTTP/1.1 401 Unauthorized
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 11 Oct 2019 09:25:53 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept
Www-Authenticate: Bearer realm="api"
X-Debug-Tag: 5da04aa15918a
X-Debug-Duration: 171
X-Debug-Link: /debug/default/view?tag=5da04aa15918a

{
  "name": "Unauthorized",
  "message": "Your request was made with invalid credentials.",
  "code": 0,
  "status": 401,
  "type": "yii\\web\\UnauthorizedHttpException"
}

Response code: 401 (Unauthorized); Time: 453ms; Content length: 181 bytes
Вот за что я не люблю линукс, так это за свои кривые, временами, руки
Usick
Сообщения: 42
Зарегистрирован: 2017.04.11, 12:07

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение Usick »

Тогда попробуйте

Код: Выделить всё

'format' => 'raw',
больше мне ничего не приходит в голову.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение Loveorigami »

De-Luxis писал(а): 2019.10.11, 12:22
Не подходит. Нужно чтоб отдавало автоматически в зависимости от заголовка.
пробуйте так в конфиге

Код: Выделить всё


    'bootstrap' => [
        'log',
        [
            'class' => yii\filters\ContentNegotiator::class,
            'formats' => [
                'application/json' => 'json',
                'application/xml' => 'xml',
            ],
        ],
    ],

https://yiiframework.com.ua/ru/doc/guid ... ormatting/
Usick
Сообщения: 42
Зарегистрирован: 2017.04.11, 12:07

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение Usick »

proctoleha писал(а): 2019.10.11, 12:29 Если вы стучитесь к контроллеру в модуле, унаследованному от \yii\rest\Controller, то должно придти все нормально, например:
Скорее всего Вы унаследовались не от того контроллера.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение yiiliveext »

proctoleha писал(а): 2019.10.11, 12:29 Если вы стучитесь к контроллеру в модуле, унаследованному от \yii\rest\Controller, то должно придти все нормально, например:
authenticator прописан на модуль, поэтому кидает исключение до того, как сработает ContentNegotiator в контроллере. Правильное решение написал Loveorigami, но можно не на все приложение подключить, а только на модуль.
De-Luxis
Сообщения: 36
Зарегистрирован: 2014.06.19, 11:16

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение De-Luxis »

proctoleha писал(а): 2019.10.11, 12:29 Если вы стучитесь к контроллеру в модуле, унаследованному от \yii\rest\Controller, то должно придти все нормально
унаследовался от \yii\rest\Controller, иначе бы после авторизации тестовые исключения в контроллере возвращались в ином формате.
Я об этом писал в стартовом топике:
De-Luxis писал(а): 2019.10.11, 09:54 Если кинуть исключение в контроллере модуля, то ошибка приходит корректно в формате json или xml, если задать соответствующее значение у заголовка.
Loveorigami писал(а): 2019.10.11, 12:46 пробуйте так в конфиге

Код: Выделить всё


    'bootstrap' => [
        'log',
        [
            'class' => yii\filters\ContentNegotiator::class,
            'formats' => [
                'application/json' => 'json',
                'application/xml' => 'xml',
            ],
        ],
    ],

https://yiiframework.com.ua/ru/doc/guid ... ormatting/

Если прописать глобально, то настройка затрагивает основное приложение.
De-Luxis
Сообщения: 36
Зарегистрирован: 2014.06.19, 11:16

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение De-Luxis »

У API своя схема авторизации. Взаимодействие идет по json и xml. Хочется чтоб все ответы и ошибки всегда возвращались в нужном клиенту формате.
При этом не затрагивая основное приложение.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение yiiliveext »

De-Luxis писал(а): 2019.10.11, 15:32 У API своя схема авторизации. Взаимодействие идет по json и xml. Хочется чтоб все ответы и ошибки всегда возвращались в нужном клиенту формате.
При этом не затрагивая основное приложение.
Ну так пропишите в модуле, вам же написали;

Код: Выделить всё

public function behaviors(): array
    {
        return [
        'contentNegotiator' => [
                'class' => ContentNegotiator::className(),
                'formats' => [
                    'application/json' => Response::FORMAT_JSON,
                    'application/xml' => Response::FORMAT_XML,
                ],
            ],
            'authenticator' => [
                'class' => HttpBasicAuth::class,
            ],
        ];
    }
De-Luxis
Сообщения: 36
Зарегистрирован: 2014.06.19, 11:16

Re: Ответ ошибки приходит в формате html, когда нужен json

Сообщение De-Luxis »

yiiliveext писал(а): 2019.10.11, 16:06 Ну так пропишите в модуле, вам же написали;
Спасибо! Это помогло.
Не сразу понял.
Ответить