Вопрос о том, как должны работать перенаправления - PullRequest
7 голосов
/ 23 апреля 2011

Итак, у меня есть веб-приложение, над которым я работаю с формой, требующей заполнения всех полей перед отправкой. Если вы попытаетесь отправить приложение без заполнения поля, оно снова загрузит страницу с ошибками. После того как вы заполните все поля и нажмете «Отправить», он перенаправляет на ту же страницу и показывает сообщение, сгенерированное из флэш-данных. См. Упрощенный пример ниже.

Контроллер приветствия:

function show_view() 
{
  $this->load->view('form');
}

function process_form()
{
  // make the 'quality' field required
  $this->form_validation->set_rules('quality', 'Quality', 'required');

  if($this->form_validation->run() == FALSE) //if the fields are NOT filled in...
  {
    echo form_error('quality');
    $this->load->view('form'); //reload the page  
  }
  else  // if the fields are filled in...
  {
    // set success message in flashdata so it can be called when page is refreshed. 
    $this->session->set_flashdata('message', 'Your rating has been saved');
    redirect(welcome/show_view);
  }
}

Теперь, чтобы проиллюстрировать мою проблему, допустим, что я нахожусь в «домашнем» представлении и перехожу к представлению «в форме». Если я заполняю поле «качество» и нажимаю «Отправить», меня перенаправляют обратно в представление «Форма» с сообщением об успешном завершении. Если я нажимаю кнопку «Назад» в браузере, он возвращает меня к «домашнему» виду. ВСЕ РАБОТАЕТ, КАК ОЖИДАЕТСЯ

Теперь давайте скажем, что я нахожусь в «домашнем» виде, и я перехожу к представлению «в форме». Если я нажимаю кнопку «Отправить», не заполняя поле «качество», представление «Форма» снова загружается и отображает сообщение об ошибке. Если я затем заполню поле «качество» и нажму кнопку «Отправить», меня перенаправят обратно в представление «Форма» с сообщением об успехе. Проблема в том, что, если я нажимаю кнопку «Назад» в браузере, теперь он возвращает меня на страницу формы с ошибкой, и мне приходится снова нажимать кнопку «Назад», чтобы вернуться к «домашнему» виду.

Какова лучшая практика кодирования, так что если пользователь отправляет форму с ошибками, он отображает ошибки, а если они исправляют ошибки и повторно отправляют форму, он отображает сообщение об успехе, и если они нажимают на браузер, он вернет их в «домашний» вид ??

Ответы [ 7 ]

3 голосов
/ 28 апреля 2011

Проблема в том, что вы используете две отдельные функции для обработки формы. Документы класса проверки формы не очень хорошо объясняют это, и мне потребовалось некоторое время, чтобы понять это, но form_validation-> run () возвращает false, если есть ошибка, но также, если это запрос GET, и впоследствии учитывает запрос GET в связанных функциях, таких как form_error () и validation_errors (), set_value () и т. д.

Лучшая практика в КИ (и в целом) заключается в следующем:

class Welcome extends CI_Controller{

function home(){
    $this->load->view('home');
}

function form() 
{
    // make the 'quality' field required
    $this->form_validation->set_rules('quality', 'Quality', 'required');

    // If the fields are NOT filled in...
    // or if there isn't a POST! (check the Form_validation.php lib to confirm)
    if ( $this->form_validation->run() === FALSE) 
    {
         // This form_error() function actually doesn't do anything if there 
         // wasn't a form submission (on a GET request)
         echo form_error('quality');
         $this->load->view('form'); // load or reload the page
    }
    else  // if the fields are filled in...
    {
         // set success message in flashdata so it can be 
         // called when page is redirected. 
         $this->session->set_flashdata('message', 'Your rating has been saved');
         redirect('welcome/home','location', 303);
         exit;
    }

}

тогда в представлении есть форма action="welcome/form"

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

function form_error($field = '', $prefix = '', $suffix = '')
{
    if (FALSE === ($OBJ =& _get_validation_object()))
    {
        return '';
    }

    return $OBJ->error($field, $prefix, $suffix);
}

Когда они не POST, они отображаются как обычно и имеют естественный поток страниц, который вы ищете.

Не имеет отношения к вопросу, но сбивает с толку / заслуживает внимания класс проверки формы ... если вы используете фильтры, такие как xss_clean, prep_url и т. Д. В поле параметров, он фактически заполняет для вас массив $ _POST, так что вы не должны не нужно ничего делать.

Иногда стоит взглянуть на внутреннюю часть источника CI, там есть некоторые умные вещи, которые не совсем очевидны.

3 голосов
/ 27 апреля 2011

Я ожидаю, что форма перенаправит меня на страницу со списком ресурсов, где ресурс - это сущность, которую пользователь отправлял изначально.

Если пользователь добавляет новую запись в ресурс, он ожидает увидеть эту запись в списке после успешной отправки формы.

Если форма находится на той же странице, вы все равно должны сделать перенаправление на основе location вместо обновления http. Код состояния для этого варианта использования: 303 См. Другое .

через Википедию HTTP 303 Код состояния

Вот что я бы сделал, учитывая ваш сценарий.

function home(){
  $this->load->view('home');
}

function show_view() 
{
    $this->load->view('form');
}

function process_form()
{
    // make the 'quality' field required
    $this->form_validation->set_rules('quality', 'Quality', 'required');

 if($this->form_validation->run() === FALSE) //if the fields are NOT filled in...
 {
    echo form_error('quality');
    $this->load->view('form'); //reload the page  
 }
 else  // if the fields are filled in...
 {
    // set success message in flashdata so it can be called when page is redirected. 
    $this->session->set_flashdata('message', 'Your rating has been saved');
    redirect('welcome/home','location', 303);
    exit;
 }

}
1 голос
/ 02 мая 2011

Объект окна DOM обеспечивает доступ к истории браузера через объект истории. Он предоставляет полезные методы и свойства, которые позволяют перемещаться по истории пользователя назад и вперед, а также - начиная с HTML5 - манипулировать содержимым стека истории. https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history

Другое дело - отправить форму с помощью ajax! и заполнить сообщения об ошибках или об успехе, основываясь на ответе ... (XML, JSON ...), конечно, это не совсем то, что вы искали, но у него есть много преимуществ в пользовательском опыте, которые вы пытаетесь улучшить.

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

Кроме того, новый JavaScript-код HTML5 изменяет состояние истории или как его там называют. Таким образом, вы можете определить в своей программе, как сайт должен вести себя при изменении страницы, с помощью кнопки «Назад» и ... вскоре вы увидите множество кнопок «Назад», интегрированных и в веб-интерфейс.

1 голос
/ 26 апреля 2011

Единственный надежный способ сообщить браузеру, что он игнорирует / удаляет страницы в своей истории, с помощью команды javascript:

location.replace(url);

это выполняет перенаправление на стороне клиента, но заменяет текущее местоположение в истории браузера.,Или же вообще не переходить на новую страницу (вызов ajax).

Если вы используете POST в качестве метода в вашей форме, они получат сообщение об ошибке, заявив, что они должны повторно отправить информацию на сервер, чтобы вернуться,что отпугнет большинство людей от использования кнопки «назад».

Вы можете использовать шаблон nonce, где вы генерируете метку времени или другой уникальный идентификатор, помещаете его в сеанс и скрытое поле в своей функции show_view при созданииформы, а затем проверьте ее на соответствие вашей функции процесса и удалите ее из сеанса, если есть совпадение.Таким образом, если они попытаются отправить одну и ту же форму дважды (нажав кнопку «Назад»), вы можете обнаружить ее, обнаружив, что совпадения нет, и перенаправить ее на безошибочную show_view или домашнюю страницу или куда угодно.

Вы также захотите убедиться, что ваши истечения срока действия и заголовки управления кэшем заставляют веб-браузер каждый раз подключаться к серверу по сравнению с использованием только его локального кэша.http://www.web -caching.com / mnot_tutorial / notes.html # IMP-SERVER

Для игроков или хуже, большинство веб-сайтов игнорируют такие проблемы с кнопками возврата, как эти

1 голос
/ 26 апреля 2011

Я некоторое время пользуюсь Symfony и считаю, что решение Symfony является оптимальным. Это работает так, что у вас есть маршрутизация (я думаю, что у CI тоже есть маршрутизация: CI маршрутизация ), и в вашем контроллере вы можете сделать что-то подобное в вашем методе "create":

if the form is valid
  set flash notice message
  redirect to (your homepage or something else defined in your routing file)
else
  set flash error message
  set the current view to form

Действие вашей формы - это тот же контроллер с действием "создать" (которое может быть достигнуто только через запрос POST). Форма, которую вы можете получить с помощью запросов GET, - это «новый» метод. Поэтому, если вы нажмете «Отправить» в своей форме, вы перейдете к методу создания, но новый метод генерирует вашу форму впервые. Если ваша форма не подтверждена, вы остаетесь там с сообщениями об ошибках. Если вы нажмете назад, вы получите новую форму, но если форма проверяет ваше действие (метод), вы перенаправляетесь на пользовательскую страницу, которую вы установили ранее в операторе if выше.

Этот метод работает и с ajax, вы можете проверить в своем действии, является ли запрос XHTTP, вы просто возвращаете, если форма проверяется или нет, и вы можете обрабатывать вещи в javascript. Я думаю, что это лучший способ обработки форм, и если у вашего пользователя не включен javascript, он все равно может использовать «стандартный» способ. И, кстати: «создать» и «новый» использует один и тот же шаблон (вид). Надеюсь, я все прояснил.

0 голосов
/ 26 апреля 2011

Насколько я знаю - и могу найти - не существует надежного способа отследить событие истории назад, и все решения основаны на Javascript, так что вы могли бы также создать форму AJAX.Я бы сказал, что единственно возможным решением, не являющимся javascript, будет либо iframe (который никому не нравится), либо то, что предлагает BraedenP.

Лично, если вы действительно хотите эту функциональность, я бы создал форму AJAX ипросто не работайте так для не-javascript-пользователей (они должны иметь немного упрощенный интерфейс).

Это всегда хорошая практика - добавлять след на хлебную крошку или кнопку назад, так чтоможет также помочь.

0 голосов
/ 23 апреля 2011

Самый простой способ сделать то, что вы предлагаете, это отправить значения формы в ваш валидатор PHP, используя HTTPRequest (AJAX), а затем показать ошибки с помощью JavaScript.Таким образом, вам не нужно будет выполнять какое-либо перенаправление, а кнопка «Назад» все равно вернет вас домой.

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

Хотя я действительно рекомендовал бы использовать отправку форм AJAX в качестве решения этой проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...