странное поведение с использованием «перенаправления назад» и двух или более вкладок с Laravel 5, только на сервере - PullRequest
0 голосов
/ 23 мая 2018

У меня большая и странная проблема с использованием Laravel 5.4 на виртуальном хостинге.

Когда laravel использует «redirect back», он перенаправляет на последнюю посещенную страницу.

Давайте представим себе следующее:

У нас есть сайт с 2 разделами: товары и категории.Мы заходим на страницу продуктов и URL site.com / products .На этой странице есть 3 кнопки: новая, редактировать и галерея.

Мы хотим отредактировать producto с идентификатором 3 ( ... / products / 3 / edit ), чтобы мы отредактировали его информацию исохрани это.Никаких проблем здесь, проверки были ок.

НО нам нужно снова отредактировать продукт, чтобы перейти на страницу редактирования ( ... / products / 3 / edit ).Поле имени может содержать до 10 букв, но мы ввели 11. Мы открываем страницу категорий на другой вкладке ( .. / category ).Затем мы нажимаем кнопку «сохранить», но проверка не удастся, потому что поле имени содержит 11 букв.

И бум! Переадресация Laravel на страницу категорий , потому что это была последняя открытая страница, но она должна перенаправить нас на страницу редактирования .

Это происходит, если я использую запрос формыvalidation "(public function update (ExampleRequest $ request) {...})

или если я использую простую проверку запроса ($ request-> validate (['title' => 'max: 10,...]);)

В обоих примерах одинаковая проблема.

С другой стороны, при работе с контроллерами, если я использую return redirect () -> back () ... или return Redirect :: back () ... , происходит то же самое, он перенаправляет на последнюю открытую страницу.

Итак, когда я создаю, обновляю, удаление и т. д., если проверка не пройдена или если я использую redirect () -> back (), это перенаправит меня на последнюю открытую страницу, и если я открою страницу в другой вкладке, эта страница будет там, где «перенаправление»отправит мне.Если я использую только 1 вкладку, все работает нормально.

Это происходит со всеми моими формами и только на сервере , локальная среда в порядке.

Теперь мойкод:

.htaccess

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    # To switch to PHP 7
    AddType application/x-httpd-php56 .php

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www.example.com [NC]
    RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]

    RewriteEngine On

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

Контроллер

use App\Http\Requests\ProductRequest;

public function update(ProductRequest $request, $id)
{
  $product = Product::findOrFail($id);
  $product->update( $request->all() );

  $msgResponse = [...message...];

  return Redirect::to('/products')->with($msgResponse);
}

ProductRequest

<?php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class ProductRequest extends FormRequest{

  public function authorize(){
    return true;
  }

  public function rules()
  {
    return [
      'title' => 'required|max:10|...',
      'otherfield' => ['required', Rule::in([...]),],
      ...
    ];
  }
}

Сайт:

PHP 7.0, Общий сервер, Laravel 5.4

Пожалуйста, помогите!: (

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Как сказал (или набрал = p) @Aken Roberts, проблема в заголовке Referer

Я пытался проверить, что отправляется в $ запрос, используя dd (...) :

public function xxx(Request $request, $id){
      dd($request);
      ...

В моей локальной среде , текущий URLпринимается внутри server , headers и session :

+server: ServerBag {#42 ▼
    #parameters: array:29 [▼
      ...
      "HTTP_REFERER" => ".../products/3/edit"
      ...
...
..
+headers: HeaderBag {#44 ▼
    #headers: array:12 [▼
      ...
      "referer" => array:1 [▼
        0 => ".../products/3/edit"
        ]
      ...
...
..
#session: Store {#409 ▼
    ...
    #attributes: array:4 [▼
      ...
      "_previous" => array:1 [▼
        "url" => ".../products/3/edit"
        ]
      ...

Объект session может измениться, если посещенныйдругая страница в другой вкладке, но это не проблема с локальной средой, потому что у нас есть HTTP_REFERER и referer

Но на сервере , HTTP_REFERER и referer не существует, только url внутри сеанса .

Так что мне нужно выяснить, почемуэто происходит так. Я не хочу добавлять конкретный URL для каждой формы, проверок и т. д. 〜.〜

Я не уверен, но я думаю о поиске нового хостинга, возможно, digitalocean,Линода и рекламаd SSL-сертификат, потому что мне пришлось внести некоторые изменения, чтобы использовать общий хостинг (я следовал за этим видео , мин. 5:43), но это дополнительная плата для клиента.

1 Ответ

0 голосов
/ 24 мая 2018

Проверка Laravel, Redirector и все остальное, что определяет предыдущий или «обратный» URL, используют ту же логику.Метод Illuminate\Routing\UrlGenerator::previous() сначала проверяет, существует ли заголовок HTTP-запроса Referer - если это так, он использует этот URL-адрес.Если нет, он проверяет специальное значение сеанса «предыдущий URL», которое Laravel сохраняет при каждом запросе, когда сеансы включены, и использует его.

На основании вашего объяснения кажется, что заголовок Referer не отправляется илираспознается, и Laravel возвращается к предыдущему значению сеанса URL.Одна возможность в соответствии с MDN Docs :

Заголовок Referer не отправляется браузерами, если используется незащищенный HTTP-запрос и ссылающаяся страница была получена по безопасному протоколу (HTTPS).).

Кроме того, я не уверен, что может привести к тому, что Реферер будет пропущен / проигнорирован.

Однако я могу предположить, что вы не полагаетесь на предыдущее Laravel./ back и вместо этого указывайте, какие URL-адреса вы хотите перенаправлять, когда это возможно.

Для запроса формы это очень просто.Существует три различных свойства, которые вы можете выбрать для установки URL перенаправления:

/**
 * The URI to redirect to if validation fails.
 *
 * @var string
 */
protected $redirect;

/**
 * The route to redirect to if validation fails.
 *
 * @var string
 */
protected $redirectRoute;

/**
 * The controller action to redirect to if validation fails.
 *
 * @var string
 */
protected $redirectAction;

Для других более «автоматических» решений недопустимый запрос обычно приводит к выдаче Illuminate\Validation\ValidationException.Вы можете поймать это и изменить его, добавив redirectTo URL:

try {
    $request->validate([ /* rules */ ]);
} catch (ValidationException $e) {
    $e->redirectTo(route('route.name'));
    throw $e;
}

Было бы неплохо избегать использования этого в нескольких местах, поэтому я надеюсь, что вы сможете добраться до нижней части Refererвыпуск!

...