Yii2 302 ошибка

Ответы ¶

Когда приложение заканчивает обработку запроса, оно генерирует объект ответа
и отправляет его пользователю. Объект ответа содержит такие данные, как HTTP-код состояния, HTTP-заголовки и тело ответа.
Конечная цель разработки Web-приложения состоит в создании объектов ответа на различные запросы.

В большинстве случаев вам придется иметь дело с компонентом приложения response,
который по умолчанию является экземпляром класса yiiwebResponse. Однако Yii также позволяет вам создавать собственные
объекты ответа и отправлять их пользователям. Это будет рассмотрено ниже.

В данном разделе мы опишем, как составлять ответы и отправлять их пользователям.

Код состояния ¶

Первое, что вы делаете при построении ответа, — определяете, был ли успешно обработан запрос. Это реализуется заданием
свойству yiiwebResponse::$statusCode значения, которое может быть одним из валидных
HTTP-кодов состояния. Например, чтобы показать, что запрос был
успешно обработан, вы можете установить значение кода состояния равным 200:

Yii::$app->response->statusCode = 200;

Однако в большинстве случаев явная установка не требуется так как значение yiiwebResponse::$statusCode
по умолчанию равно 200. Если вам нужно показать, что запрос не удался, вы можете выбросить соответствующее
HTTP-исключение:

throw new yiiwebNotFoundHttpException;

Когда обработчик ошибок поймает исключение, он извлечёт код состояния
из исключения и назначит его ответу. Исключение yiiwebNotFoundHttpException в коде выше
представляет HTTP-код состояния 404. В Yii предопределены следующие HTTP-исключения:

  • yiiwebBadRequestHttpException: код состояния 400.
  • yiiwebConflictHttpException: код состояния 409.
  • yiiwebForbiddenHttpException: код состояния 403.
  • yiiwebGoneHttpException: код состояния 410.
  • yiiwebMethodNotAllowedHttpException: код состояния 405.
  • yiiwebNotAcceptableHttpException: код состояния 406.
  • yiiwebNotFoundHttpException: код состояния 404.
  • yiiwebServerErrorHttpException: код состояния 500.
  • yiiwebTooManyRequestsHttpException: код состояния 429.
  • yiiwebUnauthorizedHttpException: код состояния 401.
  • yiiwebUnsupportedMediaTypeHttpException: код состояния 415.

Если в приведённом выше списке нет исключения, которое вы хотите выбросить, вы можете создать его, расширив класс
yiiwebHttpException, или выбросить его напрямую с кодом состояния, например:

throw new yiiwebHttpException(402);

Вы можете отправлять HTTP-заголовки, работая с коллекцией заголовков компонента response:

$headers = Yii::$app->response->headers;

// добавить заголовок Pragma. Уже имеющиеся Pragma-заголовки НЕ будут перезаписаны.
$headers->add('Pragma', 'no-cache');

// установить заголовок Pragma. Любые уже имеющиеся Pragma-заголовки будут сброшены.
$headers->set('Pragma', 'no-cache');

// удалить заголовок (или заголовки) Pragma и вернуть их значения массивом
$values = $headers->remove('Pragma');

Информация: названия заголовков не чувствительны к регистру символов. Заново зарегистрированные заголовки не отсылаются
пользователю до вызова yiiwebResponse::send().

Тело ответа ¶

Большинство ответов должны иметь тело, содержащее то, что вы хотите показать пользователям.

Если у вас уже имеется отформатированная строка для тела, вы можете присвоить её свойству yiiwebResponse::$content
объекта запроса:

Yii::$app->response->content = 'hello world!';

Если ваши данные перед отправкой конечным пользователям нужно привести к определённому формату, вам следует установить значения
двух свойств: format и data. Свойство format
определяет, в каком формате следует возвращать данные из data. Например:

$response = Yii::$app->response;
$response->format = yiiwebResponse::FORMAT_JSON;
$response->data = ['message' => 'hello world'];

Yii из коробки имеет поддержку следующих форматов, каждый из которых реализован классом форматтера.
Вы можете настроить эти форматтеры или добавить новые через свойство yiiwebResponse::$formatters.

  • HTML: реализуется классом yiiwebHtmlResponseFormatter.
  • XML: реализуется классом yiiwebXmlResponseFormatter.
  • JSON: реализуется классом yiiwebJsonResponseFormatter.
  • JSONP: реализуется классом yiiwebJsonResponseFormatter.

Хотя тело запроса может быть явно установлено показанным выше способом, в большинстве случаев вы можете задавать его неявно
через возвращаемое значение методов действий. Типичный пример использования:

public function actionIndex()
{
    return $this->render('index');
}

Действие index в коде выше возвращает результат рендеринга представления index. Возвращаемое значение будет взято
компонентом response, отформатировано и затем отправлено пользователям.

Так как по умолчанию форматом ответа является HTML, в методе действия следует
вернуть строку. Если вы хотите использовать другой формат ответа, необходимо настроить его перед отправкой данных:

public function actionInfo()
{
    Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;
    return [
        'message' => 'hello world',
        'code' => 100,
    ];
}

Как уже было сказано, кроме использования стандартного компонента приложения response вы также можете создавать свои
объекты ответа и отправлять их конечным пользователям. Вы можете сделать это, возвращая такой объект в методе действия:

public function actionInfo()
{
    return Yii::createObject([
        'class' => 'yiiwebResponse',
        'format' => yiiwebResponse::FORMAT_JSON,
        'data' => [
            'message' => 'hello world',
            'code' => 100,
        ],
    ]);
}

Примечание: создавая собственные объекты ответов, вы не сможете воспользоваться конфигурацией компонента response,
настроенной вами в конфигурации приложения. Тем не менее, вы можете воспользоваться
внедрением зависимости, чтобы применить общую конфигурацию к вашим новым объектам ответа.

Перенаправление браузера ¶

Перенаправление браузера основано на отправке HTTP-заголовка Location. Так как данная возможность широко применяется,
Yii имеет средства для её использования.

Вы можете перенаправить браузер пользователя на URL-адрес, вызвав метод yiiwebResponse::redirect(). Этот метод
использует указанный URL-адрес в качестве значения заголовка Location и возвращает сам объект ответа. В методе действия
вы можете вызвать короткую версию этого метода — yiiwebController::redirect(). Например:

public function actionOld()
{
    return $this->redirect('https://example.com/new', 301);
}

В приведённом выше коде метод действия возвращает результат redirect(). Как говорилось выше, объект ответа,
возвращаемый методом действия, будет использоваться в качестве ответа конечным пользователям.

В коде, находящемся вне методов действий, следует использовать yiiwebResponse::redirect() и непосредственно после
него — метод yiiwebResponse::send(). Так можно быть уверенным, что к ответу не будет добавлено нежелательное
содержимое.

Yii::$app->response->redirect('https://example.com/new', 301)->send();

Информация: По умолчанию метод yiiwebResponse::redirect() устанавливает код состояния ответа равным 302, сообщая
браузеру, что запрашиваемый ресурс временно находится по другому URI-адресу. Вы можете передать код состояния
301, чтобы сообщить браузеру, что ресурс перемещён навсегда.

Если текущий запрос является AJAX-запросом, отправка заголовка Location не заставит браузер автоматически
осуществить перенаправление. Чтобы решить эту задачу, метод yiiwebResponse::redirect() устанавливает значение
заголовка X-Redirect равным URL для перенаправления. На стороне клиента вы можете написать JavaScript-код для чтения
значения этого заголовка и перенаправления браузера соответственно.

Информация: Yii поставляется с JavaScript-файлом yii.js, который предоставляет набор часто используемых
JavaScript-утилит, включая и перенаправление браузера на основе заголовка X-Redirect. Следовательно, если вы
используете этот JavaScript-файл (зарегистрировав пакет ресурсов yiiwebYiiAsset), вам не нужно писать
дополнительный код для поддержки AJAX-перенаправления.

Отправка файлов ¶

Как и перенаправление браузера, отправка файлов является ещё одной возможностью, основанной на определённых HTTP-заголовках.
Yii предоставляет набор методов для решения различных задач по отправке файлов. Все они поддерживают HTTP-заголовок range.

  • yiiwebResponse::sendFile(): отправляет клиенту существующий файл.
  • yiiwebResponse::sendContentAsFile(): отправляет клиенту строку как файл.
  • yiiwebResponse::sendStreamAsFile(): отправляет клиенту существующий файловый поток как файл.

Эти методы имеют одинаковую сигнатуру и возвращают объект ответа. Если отправляемый файл очень велик, следует
использовать yiiwebResponse::sendStreamAsFile(), так как он более эффективно использует оперативную память.
Следующий пример показывает, как отправить файл в действии контроллера:

public function actionDownload()
{
    return Yii::$app->response->sendFile('path/to/file.txt');
}

Чтобы быть уверенным, что к ответу не будет добавлено никакое
нежелательное содержимое, при вызове метода yiiwebResponse::sendFile() вне методов action, следует вызвать сразу после него yiiwebResponse::send().

Yii::$app->response->sendFile('path/to/file.txt')->send();

Некоторые Web-серверы поддерживают особый режим отправки файлов, который называется X-Sendfile. Идея в том, чтобы
перенаправить запрос файла Web-серверу, который отдаст файл пользователю самостоятельно. В результате Web-приложение
может завершиться раньше, пока Web-сервер ещё пересылает файл. Чтобы использовать эту возможность, воспользуйтесь
методом yiiwebResponse::xSendFile(). Далее приведены ссылки на то, как включить X-Sendfile для популярных
Web-серверов:

  • Apache: X-Sendfile
  • Lighttpd v1.4: X-LIGHTTPD-send-file
  • Lighttpd v1.5: X-Sendfile
  • Nginx: X-Accel-Redirect
  • Cherokee: X-Sendfile and X-Accel-Redirect

Отправка ответа ¶

Содержимое ответа не отправляется пользователю до вызова метода yiiwebResponse::send(). По умолчанию он вызывается
автоматически в конце метода yiibaseApplication::run(). Однако чтобы ответ был отправлен немедленно, вы можете
вызвать этот метод явно.

Для отправки ответа метод yiiwebResponse::send() выполняет следующие шаги:

  1. Инициируется событие yiiwebResponse::EVENT_BEFORE_SEND.
  2. Для форматирования данных ответа в содержимое ответа
    вызывается метод yiiwebResponse::prepare() .
  3. Инициируется событие yiiwebResponse::EVENT_AFTER_PREPARE.
  4. Для отправки зарегистрированных HTTP-заголовков вызывается метод yiiwebResponse::sendHeaders().
  5. Для отправки тела ответа вызывается метод yiiwebResponse::sendContent().
  6. Инициируется событие yiiwebResponse::EVENT_AFTER_SEND.

Повторный вызов yiiwebResponse::send() игнорируется. Это означает, что если ответ уже отправлен, то к нему уже
ничего не добавить.

Как видно, метод yiiwebResponse::send() инициирует несколько полезных событий. Реагируя на
эти события, можно настраивать или декорировать ответ.

Ответы

Когда приложение заканчивает обработку запроса, оно генерирует объект [[yiiwebResponse|ответа]]
и отправляет его пользователю. Объект ответа содержит такие данные, как HTTP-код состояния, HTTP-заголовки и тело ответа.
Конечная цель разработки Web-приложения состоит в создании объектов ответа на различные запросы.

В большинстве случаев вам придется иметь дело с компонентом приложения response,
который по умолчанию является экземпляром класса [[yiiwebResponse]]. Однако Yii также позволяет вам создавать собственные
объекты ответа и отправлять их пользователям. Это будет рассмотрено ниже.

В данном разделе мы опишем, как составлять ответы и отправлять их пользователям.

Код состояния

Первое, что вы делаете при построении ответа, — определяете, был ли успешно обработан запрос. Это реализуется заданием
свойству [[yiiwebResponse::statusCode]] значения, которое может быть одним из валидных
HTTP-кодов состояния. Например, чтобы показать, что запрос был
успешно обработан, вы можете установить значение кода состояния равным 200:

Yii::$app->response->statusCode = 200;

Однако в большинстве случаев явная установка не требуется так как значение [[yiiwebResponse::statusCode]]
по умолчанию равно 200. Если вам нужно показать, что запрос не удался, вы можете выбросить соответствующее
HTTP-исключение:

throw new yiiwebNotFoundHttpException;

Когда обработчик ошибок поймает исключение, он извлечёт код состояния
из исключения и назначит его ответу. Исключение [[yiiwebNotFoundHttpException]] в коде выше
представляет HTTP-код состояния 404. В Yii предопределены следующие HTTP-исключения:

  • [[yiiwebBadRequestHttpException]]: код состояния 400.
  • [[yiiwebConflictHttpException]]: код состояния 409.
  • [[yiiwebForbiddenHttpException]]: код состояния 403.
  • [[yiiwebGoneHttpException]]: код состояния 410.
  • [[yiiwebMethodNotAllowedHttpException]]: код состояния 405.
  • [[yiiwebNotAcceptableHttpException]]: код состояния 406.
  • [[yiiwebNotFoundHttpException]]: код состояния 404.
  • [[yiiwebServerErrorHttpException]]: код состояния 500.
  • [[yiiwebTooManyRequestsHttpException]]: код состояния 429.
  • [[yiiwebUnauthorizedHttpException]]: код состояния 401.
  • [[yiiwebUnsupportedMediaTypeHttpException]]: код состояния 415.

Если в приведённом выше списке нет исключения, которое вы хотите выбросить, вы можете создать его, расширив класс
[[yiiwebHttpException]], или выбросить его напрямую с кодом состояния, например:

throw new yiiwebHttpException(402);

HTTP-заголовки

Вы можете отправлять HTTP-заголовки, работая с [[yiiwebResponse::headers|коллекцией заголовков]] компонента response:

$headers = Yii::$app->response->headers;

// добавить заголовок Pragma. Уже имеющиеся Pragma-заголовки НЕ будут перезаписаны.
$headers->add('Pragma', 'no-cache');

// установить заголовок Pragma. Любые уже имеющиеся Pragma-заголовки будут сброшены.
$headers->set('Pragma', 'no-cache');

// удалить заголовок (или заголовки) Pragma и вернуть их значения массивом
$values = $headers->remove('Pragma');

Info: названия заголовков не чувствительны к регистру символов. Заново зарегистрированные заголовки не отсылаются
пользователю до вызова [[yiiwebResponse::send()]].

Тело ответа

Большинство ответов должны иметь тело, содержащее то, что вы хотите показать пользователям.

Если у вас уже имеется отформатированная строка для тела, вы можете присвоить её свойству [[yiiwebResponse::content]]
объекта запроса:

Yii::$app->response->content = 'hello world!';

Если ваши данные перед отправкой конечным пользователям нужно привести к определённому формату, вам следует установить значения
двух свойств: [[yiiwebResponse::format|format]] и [[yiiwebResponse::data|data]]. Свойство [[yiiwebResponse::format|format]]
определяет, в каком формате следует возвращать данные из [[yiiwebResponse::data|data]]. Например:

$response = Yii::$app->response;
$response->format = yiiwebResponse::FORMAT_JSON;
$response->data = ['message' => 'hello world'];

Yii из коробки имеет поддержку следующих форматов, каждый из которых реализован классом [[yiiwebResponseFormatterInterface|форматтера]].
Вы можете настроить эти форматтеры или добавить новые через свойство [[yiiwebResponse::formatters]].

  • [[yiiwebResponse::FORMAT_HTML|HTML]]: реализуется классом [[yiiwebHtmlResponseFormatter]].
  • [[yiiwebResponse::FORMAT_XML|XML]]: реализуется классом [[yiiwebXmlResponseFormatter]].
  • [[yiiwebResponse::FORMAT_JSON|JSON]]: реализуется классом [[yiiwebJsonResponseFormatter]].
  • [[yiiwebResponse::FORMAT_JSONP|JSONP]]: реализуется классом [[yiiwebJsonResponseFormatter]].

Хотя тело запроса может быть явно установлено показанным выше способом, в большинстве случаев вы можете задавать его неявно
через возвращаемое значение методов действий. Типичный пример использования:

public function actionIndex()
{
    return $this->render('index');
}

Действие index в коде выше возвращает результат рендеринга представления index. Возвращаемое значение будет взято
компонентом response, отформатировано и затем отправлено пользователям.

Так как по умолчанию форматом ответа является [[yiiwebResponse::FORMAT_HTML|HTML]], в методе действия следует
вернуть строку. Если вы хотите использовать другой формат ответа, необходимо настроить его перед отправкой данных:

public function actionInfo()
{
    Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;
    return [
        'message' => 'hello world',
        'code' => 100,
    ];
}

Как уже было сказано, кроме использования стандартного компонента приложения response вы также можете создавать свои
объекты ответа и отправлять их конечным пользователям. Вы можете сделать это, возвращая такой объект в методе действия:

public function actionInfo()
{
    return Yii::createObject([
        'class' => 'yiiwebResponse',
        'format' => yiiwebResponse::FORMAT_JSON,
        'data' => [
            'message' => 'hello world',
            'code' => 100,
        ],
    ]);
}

Note: создавая собственные объекты ответов, вы не сможете воспользоваться конфигурацией компонента response,
настроенной вами в конфигурации приложения. Тем не менее, вы можете воспользоваться
внедрением зависимости, чтобы применить общую конфигурацию к вашим новым объектам ответа.

Перенаправление браузера

Перенаправление браузера основано на отправке HTTP-заголовка Location. Так как данная возможность широко применяется,
Yii имеет средства для её использования.

Вы можете перенаправить браузер пользователя на URL-адрес, вызвав метод [[yiiwebResponse::redirect()]]. Этот метод
использует указанный URL-адрес в качестве значения заголовка Location и возвращает сам объект ответа. В методе действия
вы можете вызвать короткую версию этого метода — [[yiiwebController::redirect()]]. Например:

public function actionOld()
{
    return $this->redirect('https://example.com/new', 301);
}

В приведённом выше коде метод действия возвращает результат redirect(). Как говорилось выше, объект ответа,
возвращаемый методом действия, будет использоваться в качестве ответа конечным пользователям.

В коде, находящемся вне методов действий, следует использовать [[yiiwebResponse::redirect()]] и непосредственно после
него — метод [[yiiwebResponse::send()]]. Так можно быть уверенным, что к ответу не будет добавлено нежелательное
содержимое.

Yii::$app->response->redirect('https://example.com/new', 301)->send();

Info: По умолчанию метод [[yiiwebResponse::redirect()]] устанавливает код состояния ответа равным 302, сообщая
браузеру, что запрашиваемый ресурс временно находится по другому URI-адресу. Вы можете передать код состояния
301, чтобы сообщить браузеру, что ресурс перемещён навсегда.

Если текущий запрос является AJAX-запросом, отправка заголовка Location не заставит браузер автоматически
осуществить перенаправление. Чтобы решить эту задачу, метод [[yiiwebResponse::redirect()]] устанавливает значение
заголовка X-Redirect равным URL для перенаправления. На стороне клиента вы можете написать JavaScript-код для чтения
значения этого заголовка и перенаправления браузера соответственно.

Info: Yii поставляется с JavaScript-файлом yii.js, который предоставляет набор часто используемых
JavaScript-утилит, включая и перенаправление браузера на основе заголовка X-Redirect. Следовательно, если вы
используете этот JavaScript-файл (зарегистрировав пакет ресурсов [[yiiwebYiiAsset]]), вам не нужно писать
дополнительный код для поддержки AJAX-перенаправления.

Отправка файлов

Как и перенаправление браузера, отправка файлов является ещё одной возможностью, основанной на определённых HTTP-заголовках.
Yii предоставляет набор методов для решения различных задач по отправке файлов. Все они поддерживают HTTP-заголовок range.

  • [[yiiwebResponse::sendFile()]]: отправляет клиенту существующий файл.
  • [[yiiwebResponse::sendContentAsFile()]]: отправляет клиенту строку как файл.
  • [[yiiwebResponse::sendStreamAsFile()]]: отправляет клиенту существующий файловый поток как файл.

Эти методы имеют одинаковую сигнатуру и возвращают объект ответа. Если отправляемый файл очень велик, следует
использовать [[yiiwebResponse::sendStreamAsFile()]], так как он более эффективно использует оперативную память.
Следующий пример показывает, как отправить файл в действии контроллера:

public function actionDownload()
{
    return Yii::$app->response->sendFile('path/to/file.txt');
}

Чтобы быть уверенным, что к ответу не будет добавлено никакое
нежелательное содержимое, при вызове метода [[yiiwebResponse::sendFile()]] вне методов action, следует вызвать сразу после него [[yiiwebResponse::send()]].

Yii::$app->response->sendFile('path/to/file.txt')->send();

Некоторые Web-серверы поддерживают особый режим отправки файлов, который называется X-Sendfile. Идея в том, чтобы
перенаправить запрос файла Web-серверу, который отдаст файл пользователю самостоятельно. В результате Web-приложение
может завершиться раньше, пока Web-сервер ещё пересылает файл. Чтобы использовать эту возможность, воспользуйтесь
методом [[yiiwebResponse::xSendFile()]]. Далее приведены ссылки на то, как включить X-Sendfile для популярных
Web-серверов:

  • Apache: X-Sendfile
  • Lighttpd v1.4: X-LIGHTTPD-send-file
  • Lighttpd v1.5: X-Sendfile
  • Nginx: X-Accel-Redirect
  • Cherokee: X-Sendfile and X-Accel-Redirect

Отправка ответа

Содержимое ответа не отправляется пользователю до вызова метода [[yiiwebResponse::send()]]. По умолчанию он вызывается
автоматически в конце метода [[yiibaseApplication::run()]]. Однако чтобы ответ был отправлен немедленно, вы можете
вызвать этот метод явно.

Для отправки ответа метод [[yiiwebResponse::send()]] выполняет следующие шаги:

  1. Инициируется событие [[yiiwebResponse::EVENT_BEFORE_SEND]].
  2. Для форматирования [[yiiwebResponse::data|данных ответа]] в [[yiiwebResponse::content|содержимое ответа]]
    вызывается метод [[yiiwebResponse::prepare()]] .
  3. Инициируется событие [[yiiwebResponse::EVENT_AFTER_PREPARE]].
  4. Для отправки зарегистрированных HTTP-заголовков вызывается метод [[yiiwebResponse::sendHeaders()]].
  5. Для отправки тела ответа вызывается метод [[yiiwebResponse::sendContent()]].
  6. Инициируется событие [[yiiwebResponse::EVENT_AFTER_SEND]].

Повторный вызов [[yiiwebResponse::send()]] игнорируется. Это означает, что если ответ уже отправлен, то к нему уже
ничего не добавить.

Как видно, метод [[yiiwebResponse::send()]] инициирует несколько полезных событий. Реагируя на
эти события, можно настраивать или декорировать ответ.

Пытаюсь сделать телеграмм бота, установил вебхук, получил сообщение о том, что все хорошо, но телеграмм не передает данные. Получаю информацию о последнем запросе с помощью запроса api.telegram.org/botтокен/getWebhookInfo

{"ok":true,"result":{"url":"https://домен/site/webhook","has_custom_certificate":false,"pending_update_count":22,"last_error_date":1680683249,"last_error_message":"Wrong response from the webhook: 302 Found","max_connections":40,"ip_address":"ip"}}

В runtime/logs/app.log данная информация:

2023-04-05 11:17:03 [91.108.6.124][-][-][info][application] $_GET = []

$_POST = []

$_FILES = []

$_COOKIE = []

$_SERVER = [
    'REDIRECT_REDIRECT_HTTPS' => 'on'
    'REDIRECT_REDIRECT_downgrade-1_0' => ''
    'REDIRECT_REDIRECT_suppress-error-charset' => ''
    'REDIRECT_REDIRECT_STATUS' => '200'
    'REDIRECT_HTTPS' => 'on'
    'REDIRECT_downgrade-1_0' => ''
    'REDIRECT_suppress-error-charset' => ''
    'REDIRECT_STATUS' => '200'
    'HTTPS' => 'on'
    'downgrade-1_0' => ''
    'suppress-error-charset' => ''
    'HTTP_HOST' => 'домен'
    'HTTP_X_REAL_IP' => ''
    'HTTP_X_PROTOCOL' => 'HTTP/1.1'
    'HTTP_X_SERVER_IP' => ''
    'HTTP_X_FORWARDED_PROTOCOL' => 'https'
    'HTTP_X_FORWARDED_PROTO' => 'https'
    'HTTP_CONNECTION' => 'close'
    'CONTENT_LENGTH' => '443'
    'CONTENT_TYPE' => 'application/json'
    'HTTP_ACCEPT_ENCODING' => 'gzip, deflate'
    'PATH' => '/usr/bin:/bin:/usr/local/bin'
    'SERVER_SIGNATURE' => ''
    'SERVER_SOFTWARE' => 'Apache'
    'SERVER_NAME' => ''
    'SERVER_ADDR' => ''
    'SERVER_PORT' => '80'
    'REMOTE_ADDR' => ''
    'DOCUMENT_ROOT' => '/home/users/o/oktyabr/domains/домен'
    'REQUEST_SCHEME' => 'http'
    'CONTEXT_PREFIX' => ''
    'CONTEXT_DOCUMENT_ROOT' => '/home/users/o/oktyabr/domains/домен'
    'SERVER_ADMIN' => 'info@jino.ru'
    'SCRIPT_FILENAME' => '/home/users/o/oktyabr/domains/домен/frontend/web/index.php'
    'REMOTE_PORT' => '39066'
    'REDIRECT_URL' => '/frontend/web/site/webhook'
    'GATEWAY_INTERFACE' => 'CGI/1.1'
    'SERVER_PROTOCOL' => 'HTTP/1.0'
    'REQUEST_METHOD' => 'POST'
    'QUERY_STRING' => ''
    'REQUEST_URI' => '/site/webhook'
    'SCRIPT_NAME' => '/frontend/web/index.php'
    'PHP_SELF' => '/frontend/web/index.php'
    'REQUEST_TIME_FLOAT' => 1680682623.7914
    'REQUEST_TIME' => 1680682623
]

Я так понимаю из-за того, что идет переадресация ‘REDIRECT_URL’ => ‘/frontend/web/site/webhook’ получаю 302 ошибку. Как можно настроить иначе, чтобы не было переадресации?

Код проекта:
.htaccess

Options +FollowSymLinks
IndexIgnore /
RewriteEngine on

# Если запрос начинается с /admin, то заменяем на /backend/web/
RewriteCond %{REQUEST_URI} ^/admin
RewriteRule ^admin/?(.*) /backend/web/$1

# Добавляем другой запрос /frontend/web/$1
RewriteCond %{REQUEST_URI} !^/(frontend/web|backend/web|admin)
RewriteRule (.*) /frontend/web/$1

# Если frontend запрос
RewriteCond %{REQUEST_URI} ^/frontend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /frontend/web/index.php

# Если backend запрос
RewriteCond %{REQUEST_URI} ^/backend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /backend/web/index.php

В контроллере SiteController

public function actionSetWebhook()
    {
        $botToken = Yii::$app->params['telegram'];
        $webhookUrl = Yii::$app->urlManager->createAbsoluteUrl(['site/webhook']);

        $telegramApiUrl = "https://api.telegram.org/bot{$botToken}";


        $setWebhookUrl = "{$telegramApiUrl}/setWebhook?url={$webhookUrl}";
        $curl = curl_init($setWebhookUrl);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($curl);
        curl_close($curl);

        // Проверяем ответ Telegram API
        $jsonResponse = json_decode($response, true);
        print_r($jsonResponse);
        if ($jsonResponse['ok']) {
            echo 'Webhook установлен';
        } else {
            echo 'Ошибка при установке webhook: ' . $jsonResponse['description'];
        }
    }


    private function sendMessage($chatId, $message)
    {
        $botToken = Yii::$app->params['telegram'];
        $telegramApiUrl = "https://api.telegram.org/bot{$botToken}";
        $data = [
            'chat_id' => $chatId,
            'text' => $message,
        ];
        $curl = curl_init($telegramApiUrl . '/sendMessage');
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_exec($curl);
        curl_close($curl);
    }
    public function actionWebhook()
    {
        $data = file_get_contents('php://input');
        $data = json_decode($data, true);
        file_put_contents( '/home/users/o/аккаунт/domains/домен/frontend/web/message2.txt', print_r($data, true));
    }

webgrig

Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Как избавиться от 302 редиректа после ajax запроса?

Привет всем.
После выполнения GET-ajax запроса получаю 302 редирект на тот же экшин, далее браузер идет на страницу этого экшина.

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

public function actionDelImg($modelId, $imgName){
    if (Yii::$app->request->isAjax) {
        if(ImageUpload::delImg($modelId, $imgName)){
            Yii::$app->response->format = Response::FORMAT_JSON;
            return ['flag' => true];
        }
    }
}

От куда это появляется и как от этого избавится?

webgrig

Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Re: Как избавиться от 302 редиректа после ajax запроса?

Сообщение

webgrig » 2018.10.04, 11:11

Diplodok писал(а): ↑2018.10.04, 11:08
Я думаю проблема не в экшене, а в ajax запросе. Точнее в обработке ответа запроса.

Точно нет!
Если я делаю exit; в самом начале экшина, все равно получаю тот же 302 редирект

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

public function actionDelImg($modelId, $imgName){exit;
    if (Yii::$app->request->isAjax) {
        if(ImageUpload::delImg($modelId, $imgName)){
            Yii::$app->response->format = Response::FORMAT_JSON;
            return ['flag' => true];
        }
    }
}

webgrig

Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Re: Как избавиться от 302 редиректа после ajax запроса?

Сообщение

webgrig » 2018.10.04, 13:56

Все разобрался.
Этот редирект делал компонент codemixlocaleurlsUrlManager который нужен для мультиязычности сайта.
Он наботает таким образом, что если делаешь запрос по адресу в котором не указан язык, то он делает переадресацию и подставляет в адрес страницы язык.
Поэтому пришлось переписать ajax запрос таким образом, что бы в url изначально был прописан текущий язык.

webgrig

Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

When an application finishes handling a request, it generates a [[yiiwebResponse|response]] object
and sends it to the end user. The response object contains information such as the HTTP status code, HTTP headers and body.
The ultimate goal of Web application development is essentially to build such response objects upon various requests.

In most cases you should mainly deal with the response application component
which is an instance of [[yiiwebResponse]], by default. However, Yii also allows you to create your own response
objects and send them to end users as we will explain in the following.

In this section, we will describe how to compose and send responses to end users.

Status Code

One of the first things you would do when building a response is to state whether the request is successfully handled.
This is done by setting the [[yiiwebResponse::statusCode]] property which can take one of the valid
HTTP status codes. For example, to indicate the request
is successfully handled, you may set the status code to be 200, like the following:

Yii::$app->response->statusCode = 200;

However, in most cases you do not need to explicitly set the status code. This is because the default value
of [[yiiwebResponse::statusCode]] is 200. And if you want to indicate the request is unsuccessful, you may
throw an appropriate HTTP exception like the following:

throw new yiiwebNotFoundHttpException;

When the error handler catches an exception, it will extract the status code
from the exception and assign it to the response. For the [[yiiwebNotFoundHttpException]] above, it is
associated with the HTTP status 404. The following HTTP exceptions are predefined in Yii:

  • [[yiiwebBadRequestHttpException]]: status code 400.
  • [[yiiwebConflictHttpException]]: status code 409.
  • [[yiiwebForbiddenHttpException]]: status code 403.
  • [[yiiwebGoneHttpException]]: status code 410.
  • [[yiiwebMethodNotAllowedHttpException]]: status code 405.
  • [[yiiwebNotAcceptableHttpException]]: status code 406.
  • [[yiiwebNotFoundHttpException]]: status code 404.
  • [[yiiwebServerErrorHttpException]]: status code 500.
  • [[yiiwebTooManyRequestsHttpException]]: status code 429.
  • [[yiiwebUnauthorizedHttpException]]: status code 401.
  • [[yiiwebUnsupportedMediaTypeHttpException]]: status code 415.

If the exception that you want to throw is not among the above list, you may create one by extending
from [[yiiwebHttpException]], or directly throw it with a status code, for example,

throw new yiiwebHttpException(402);

You can send HTTP headers by manipulating the [[yiiwebResponse::headers|header collection]] in the response component.
For example,

$headers = Yii::$app->response->headers;

// add a Pragma header. Existing Pragma headers will NOT be overwritten.
$headers->add('Pragma', 'no-cache');

// set a Pragma header. Any existing Pragma headers will be discarded.
$headers->set('Pragma', 'no-cache');

// remove Pragma header(s) and return the removed Pragma header values in an array
$values = $headers->remove('Pragma');

Info: Header names are case insensitive. And the newly registered headers are not sent to the user until
the [[yiiwebResponse::send()]] method is called.

Response Body

Most responses should have a body which gives the content that you want to show to end users.

If you already have a formatted body string, you may assign it to the [[yiiwebResponse::content]] property
of the response. For example,

Yii::$app->response->content = 'hello world!';

If your data needs to be formatted before sending it to end users, you should set both of the
[[yiiwebResponse::format|format]] and [[yiiwebResponse::data|data]] properties. The [[yiiwebResponse::format|format]]
property specifies in which format the [[yiiwebResponse::data|data]] should be formatted. For example,

$response = Yii::$app->response;
$response->format = yiiwebResponse::FORMAT_JSON;
$response->data = ['message' => 'hello world'];

Yii supports the following formats out of the box, each implemented by a [[yiiwebResponseFormatterInterface|formatter]] class.
You can customize these formatters or add new ones by configuring the [[yiiwebResponse::formatters]] property.

  • [[yiiwebResponse::FORMAT_HTML|HTML]]: implemented by [[yiiwebHtmlResponseFormatter]].
  • [[yiiwebResponse::FORMAT_XML|XML]]: implemented by [[yiiwebXmlResponseFormatter]].
  • [[yiiwebResponse::FORMAT_JSON|JSON]]: implemented by [[yiiwebJsonResponseFormatter]].
  • [[yiiwebResponse::FORMAT_JSONP|JSONP]]: implemented by [[yiiwebJsonResponseFormatter]].
  • [[yiiwebResponse::FORMAT_RAW|RAW]]: use this format if you want to send the response directly without applying any formatting.

While the response body can be set explicitly as shown above, in most cases you may set it implicitly by the return value
of action methods. A common use case is like the following:

public function actionIndex()
{
    return $this->render('index');
}

The index action above returns the rendering result of the index view. The return value will be taken
by the response component, formatted and then sent to end users.

Because by default the response format is [[yiiwebResponse::FORMAT_HTML|HTML]], you should only return a string
in an action method. If you want to use a different response format, you should set it first before returning the data.
For example,

public function actionInfo()
{
    Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;
    return [
        'message' => 'hello world',
        'code' => 100,
    ];
}

As aforementioned, besides using the default response application component, you can also create your own
response objects and send them to end users. You can do so by returning such object in an action method, like the following,

public function actionInfo()
{
    return Yii::createObject([
        'class' => 'yiiwebResponse',
        'format' => yiiwebResponse::FORMAT_JSON,
        'data' => [
            'message' => 'hello world',
            'code' => 100,
        ],
    ]);
}

Note: If you are creating your own response objects, you will not be able to take advantage of the configurations
that you set for the response component in the application configuration. You can, however, use
dependency injection to apply a common configuration to your new response objects.

Browser Redirection

Browser redirection relies on sending a Location HTTP header. Because this feature is commonly used, Yii provides
some special support for it.

You can redirect the user browser to a URL by calling the [[yiiwebResponse::redirect()]] method. The method
sets the appropriate Location header with the given URL and returns the response object itself. In an action method,
you can call its shortcut version [[yiiwebController::redirect()]]. For example,

public function actionOld()
{
    return $this->redirect('http://example.com/new', 301);
}

In the above code, the action method returns the result of the redirect() method. As explained before, the response
object returned by an action method will be used as the response sending to end users.

In places other than an action method, you should call [[yiiwebResponse::redirect()]] directly followed by
a chained call to the [[yiiwebResponse::send()]] method to ensure no extra content will be appended to the response.

Yii::$app->response->redirect('http://example.com/new', 301)->send();

Info: By default, the [[yiiwebResponse::redirect()]] method sets the response status code to be 302 which instructs
the browser that the resource being requested is temporarily located in a different URI. You can pass in a status
code 301 to tell the browser that the resource has been permanently relocated.

When the current request is an AJAX request, sending a Location header will not automatically cause the browser
to redirect. To solve this problem, the [[yiiwebResponse::redirect()]] method sets an X-Redirect header with
the redirection URL as its value. On the client side, you may write JavaScript code to read this header value and
redirect the browser accordingly.

Info: Yii comes with a yii.js JavaScript file which provides a set of commonly used JavaScript utilities,
including browser redirection based on the X-Redirect header. Therefore, if you are using this JavaScript file
(by registering the [[yiiwebYiiAsset]] asset bundle), you do not need to write anything to support AJAX redirection.

Sending Files

Like browser redirection, file sending is another feature that relies on specific HTTP headers. Yii provides
a set of methods to support various file sending needs. They all have built-in support for the HTTP range header.

  • [[yiiwebResponse::sendFile()]]: sends an existing file to a client.
  • [[yiiwebResponse::sendContentAsFile()]]: sends a text string as a file to a client.
  • [[yiiwebResponse::sendStreamAsFile()]]: sends an existing file stream as a file to a client.

These methods have the same method signature with the response object as the return value. If the file
to be sent is very big, you should consider using [[yiiwebResponse::sendStreamAsFile()]] because it is more
memory efficient. The following example shows how to send a file in a controller action:

public function actionDownload()
{
    return Yii::$app->response->sendFile('path/to/file.txt');
}

If you are calling the file sending method in places other than an action method, you should also call
the [[yiiwebResponse::send()]] method afterwards to ensure no extra content will be appended to the response.

Yii::$app->response->sendFile('path/to/file.txt')->send();

Some Web servers have a special file sending support called X-Sendfile. The idea is to redirect the
request for a file to the Web server which will directly serve the file. As a result, the Web application
can terminate earlier while the Web server is sending the file. To use this feature, you may call
the [[yiiwebResponse::xSendFile()]]. The following list summarizes how to enable the X-Sendfile feature
for some popular Web servers:

  • Apache: X-Sendfile
  • Lighttpd v1.4: X-LIGHTTPD-send-file
  • Lighttpd v1.5: X-Sendfile
  • Nginx: X-Accel-Redirect
  • Cherokee: X-Sendfile and X-Accel-Redirect

Sending Response

The content in a response is not sent to the user until the [[yiiwebResponse::send()]] method is called.
By default, this method will be called automatically at the end of [[yiibaseApplication::run()]]. You can, however,
explicitly call this method to force sending out the response immediately.

The [[yiiwebResponse::send()]] method takes the following steps to send out a response:

  1. Trigger the [[yiiwebResponse::EVENT_BEFORE_SEND]] event.
  2. Call [[yiiwebResponse::prepare()]] to format [[yiiwebResponse::data|response data]] into
    [[yiiwebResponse::content|response content]].
  3. Trigger the [[yiiwebResponse::EVENT_AFTER_PREPARE]] event.
  4. Call [[yiiwebResponse::sendHeaders()]] to send out the registered HTTP headers.
  5. Call [[yiiwebResponse::sendContent()]] to send out the response body content.
  6. Trigger the [[yiiwebResponse::EVENT_AFTER_SEND]] event.

After the [[yiiwebResponse::send()]] method is called once, any further call to this method will be ignored.
This means once the response is sent out, you will not be able to append more content to it.

As you can see, the [[yiiwebResponse::send()]] method triggers several useful events. By responding to
these events, it is possible to adjust or decorate the response.

Понравилась статья? Поделить с друзьями:
  • Y3 6n3 ошибка мерседес
  • Xerox wc 5019 j5 сброс ошибки
  • Xmeye код ошибки 10005 как исправить
  • Xerox wc 5016 индикация ошибок
  • Xerox ошибка 017 714