Как отображать сообщения пользователю после ПУБЛИКАЦИИ + HTTP-перенаправление
-
21-08-2019 - |
Вопрос
Я использую Шаблон PRG чтобы избежать отправки нескольких форм.У этого есть, однако, серьезный недостаток — вы не можете просто echo
сообщение с подтверждением пользователю (очевидно, что пользователь не увидит страницу, он будет перенаправлен на другую).
Каковы пути решения этой проблемы?Я знаю двух из них, но ни один из них не кажется идеальным.
- Используйте пользовательский URL-адрес перенаправления, например:
http://example.com/?msg=data-saved
.Он не имеет состояния, поэтому я думаю, что он достаточно надежен.Но это создает проблемы, когда пользователь копирует ссылку, закладывает ее в закладки и т.д. - Сохраните переменную сеанса / cookie и проверяйте ее при каждой загрузке страницы.Если он установлен, снимите его и отобразите сообщение.Кажется, все в порядке, но я не уверен насчет этого — он сильно зависит от файлов cookie, это немного сложнее.
Или, может быть, есть другие способы, о которых я не знаю?Какая-то комбинация сеансов и параметров URL?Не знаю.
Какой способ, по вашему мнению, самый лучший?У какого из них меньше всего недостатков?Каковы плюсы и минусы?
Решение
Практически каждый веб-сайт, который позволяет пользователям входить в систему, делает это, полагаясь на файл cookie.Это не идеальное решение, но это лучшее, что у нас есть.
Кроме того, обработка сеанса - это одна из тех вещей, о которых обычно заботится платформа веб-разработки за вас.
Другие советы
Есть несколько других вопросов о переполнении стека, которые касаются этого, хотя я не думаю, что какие-либо из них так четко описывают проблему.Вот несколько:
- Как мне реализовать шаблон Post / Redirect / Get в asp.net Веб-формах?
- Ответ.Перенаправление с POST вместо Get?
- И то, и другое HTTP GET с телом запроса и Может ли HTTP GET легально содержать контент? подойдите к проблеме, и обсуждения достойны прочтения.
- Как мне поддерживать ошибки ModelState при использовании RedirectToAction?
Большинство удобных решений основаны на сеансе или имеют более серьезные недостатки (такие как встраивание сообщения в строку запроса).
Если вы не можете гарантировать, что у вас будут сеансы, другим (довольно дорогостоящим) методом является перенаправление на разные представления в зависимости от результата отправки формы.Например, вы можете перенаправить на EditWidgetView
, EditWidgetSaveSuccessfulView
, или EditWidgetSaveErrorView
(или, возможно, вы просто не перенаправляете на ошибки).В некоторых языках и фреймворках это непрактично до такой степени, что заставляет вас вообще отказаться от показа сообщений о подтверждении / ошибках, но в других это может стоить того.
Если вы по какой-либо причине не хотите полагаться на сеансы, вы могли бы использовать переменную Get / пользовательский URL, а затем, если эта переменная присутствует, проверьте ссылку.Если ссылка правильная, то выведите на экран сообщение.Да, это добавляет уверенности в том, что ссылки отправляются для отображения сообщения с подтверждением, но в остальном вы полагаетесь на сеансы (которые, хотя и надежны, также не на 100% идеальны для всех решений).
И, честно говоря, некоторые крупные сайты, которые обычно довольно хорошо разбираются в такого рода вещах, просто вставляют "actiondone= true" в URL.(Я заметил, что Facebook делает это в некоторых местах.)
Это зависит от того, на какой платформе вы работаете.
Ruby on Rails вызывает этот flash[:notice] = "Ваше действие было выполнено", ASP.NET MVC вызывает этот TempData["notice"] = "Ваше действие было выполнено"...
По сути, они просто хранят данные в HttpSession только для одного рейса туда и обратно.Таким образом, вы можете получить данные по другому веб-запросу.
Очень поздно приступаю к этому обсуждению..
Вы могли бы использовать комбинацию двух предложенных вариантов.
После запроса POST клиент перенаправляется (303) на URL, указывающий, что на этот запрос может быть ответное сообщение:
Client: GET http://example.com/foo.cgi
Server: 200 Ok
Client: POST http://example.com/bar.cgi
Server: 303 http://example.com/foo.cgi?msg=true
Если в msg
аргумент заключается в true
сообщение будет просмотрено в сеансе и (если найдено) включено в ответ клиенту.
Если в msg
аргумент заключается в ! true
(или отсутствует), шаг поиска пропускается.
С помощью этого решения вы предотвращаете отображение фактического сообщения в URL-адресе, URL-адрес указывает только на то, что сообщение могло быть.Кроме того, сообщение отображается только тогда, когда это необходимо (= когда оно найдено в сеансе).
Другим преимуществом является то, что это решение также позволяет включать надлежащий контроль денежных средств в HTTP-ответы.
Я использую метод переменной сеанса.Мне не очень нравится встраивать сообщения об ошибках для отображения в URL, особенно с отмеченными вами проблемами сохранения / совместного использования URL, и мне нравится, что если пользователь перезагрузит целевую страницу, это будет чистый экземпляр.