Laravel: исключить маршрут из истории URL

#php #laravel

#php #laravel

Вопрос:

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

Теперь у меня есть форма (с использованием блейда), куда эти изображения загружаются в виде небольшого предварительного просмотра текущего значения. Когда результирующий запрос проверяется и содержит ошибки, класс FormRequest Laravel перенаправит на $this->redirector->getUrlGenerator()->previous() .

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

Мой вопрос:

Как я могу исключить один конкретный маршрут из истории URLGenerator, чтобы ->previous() вызов возвращал не URL изображения, а URL формы?

Спасибо 🙂

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

1. Покажите нам какой-нибудь код для вашей логики

Ответ №1:

Я нашел решение своей проблемы, которое работает — на мой взгляд — лучше, чем ранее предложенный ответ.

Я создал новую группу промежуточного программного обеспечения в Kernel классе, где я заменил промежуточное программное обеспечение IlluminateSessionMiddlewareStartSession::class расширенным классом, который переопределяет handle метод. Мой метод в основном выполняет то же самое, что и исходный, но он не вызывает $this->storeCurrentUrl($request, $session); .

Таким образом, любой маршрут с этой группой промежуточного программного обеспечения не будет добавлен в историю URL-адресов Laravel. Затем я зарегистрировал новую группу маршрутов в RouteServiceProvider , которая использует мою новую группу промежуточного программного обеспечения.

Таким образом, перенаправление Laravel по умолчанию на предыдущий URL-адрес работает, поскольку все маршруты хранения не будут включены в историю URL-адресов.

Ответ №2:

Я столкнулся с точно такой же проблемой, запрашивая изображения с Amazon S3 через контроллер, который перепутал историю URL-адресов Laravel. Я придумал следующий «халтурный» однострочник:

 request()->headers->set('X-Requested-With', 'XMLHttpRequest');        
  

Когда эта строка присутствует в контроллере, обслуживающем изображение, storeCurrentUrl() in setPreviousUrl() вызываться не будет. Я зарегистрировал новое промежуточное программное обеспечение под названием «silent» в laravel, чтобы я мог использовать его более простым способом при маршрутизации в web.php .

Ответ №3:

  • Вы не должны зависеть от предыдущих сгенерированных URL-адресов вашего сайта. На мой взгляд, это плохая практика.

    • Допустим, у вас была простая форма на одной странице и другая простая форма на другой странице (которую пользователь открыл на другой вкладке). Теперь, если последний был отправлен позже, и пользователь заполнял первую форму, тогда вы бы отображали ошибки первой формы во второй форме страницы, что очень нежелательно.
  • Лучший вариант — использовать именованные маршруты. Вам больше не придется зависеть от истории маршрутов URL-адресов, и он совершенно надежен для перенаправления пользователя на сам маршрут формы. Я предполагаю, что вы используете именованные маршруты, то есть даете имена своим маршрутам. Что-то вроде приведенного ниже-

Маршрут:

 <?php

Route::get('/your-form-route',['as' => 'form-name-route','uses' => 'SomeController@someMethod']);
  

Метод контроллера: (после отправки формы)

 <?php

class SomeController{
 public function processInput(Request $request){
   $validator = Validator::make(.....);

   ....
   ....
   if($validator->fails())
        return redirect()->route('form-name-route')->withErrors($validator->errors())->withInput();
   }
}
  

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

1. Возможно, раньше было неясно: я специально не реализовывал перенаправление на предыдущий URL, ядро фреймворка Laravel делает это само по себе при использовании FormRequests. FormRequest Класс реализует метод, getRedirectUrl() который по умолчанию возвращает $this->redirector->getUrlGenerator()->previous() . Смотрите github.com/laravel/framework/blob/5.8/src/Illuminate/Foundation/… Я искал решение, которое работало бы с классами Laravel по умолчанию.