Иногда есть необходимость показывать пользователю уведомления после редиректа уже на новой странице.
В статье описаны достоинства и недостатки нескольких реализаций таких уведомлений,
Есть внутренний поиск по сайту:
Хотим в случаях когда результат только один сразу редиректить на его страницу, минуя полу-бесполезный список:
Просто так это делать плохо: что если наш поиск нашёл совсем не того Васю Пупкина которого искал пользователь, например, если другого у нас попросту нет?
Решение: на странице с профилем Васи мы будем выводить уведомление, что у нас есть только один Вася Пупкин и на его страницу вы сейчас смотрите:
Перед тем как перенапавить пользователя на страницу Васи мы пишем в сессионное хранилище признак того, что хотим показать ему уведомление.
Грубый пример на PHP:
Когда показываем страницу Васи, проверяем флаг:
Чем плохо такое решение?
1. Если пользователь начнёт открывать много страниц одновременно, то в зависимости от реализации может наблюдать разные интересные эффекты (мелочи по сути).
2. Если вы захотите целиком кэшировать страницы, проблемы с учётом зависимостей не заставят себя долго ждать.
1-ую проблему можно решать рядом способов, но по сути полученное хитросплетение условий и таймаутов лишний раз намекнёт на то что в сессии этой информации не место.
UPD: Кстати если вместо сессии использовать куки то вторая проблема обретает решение. Жаль что первая обостряется только сильнее :)
Чтобы обойти эти две проблемы информацию о том показывать уведомление или нет надо передавать в URL-e.
Приходим к очередному решению.
Тут всё просто — просто кидаем пользователя, скажем, на location/vasya/?show_notice=1:
и при рендериге шаблона проверяем флаг:
Самый настоящий REST и только две неприятности:
Ещё одно место куда можно запихнуть информацию об уведомлении это хэш.
Получится что-то вроде:
тогда пользователя перебросит, например, на localhost/vasya/#show_notice
В отличие от GET параметров, сервер эту информацию попросту не получит так что показать уведомление получится только на клиенте, например, с помощью Javascript + PrototypeJS:
Сразу после загрузки страницы localhost/vasya/#show_notice адрес сменится (без перезагрузки!) на localhost/vasya/# (назойливую решётку убрать никак не получается, но ничего страшного в ней опять же нет).
В статье описаны достоинства и недостатки нескольких реализаций таких уведомлений,
Пример
Есть внутренний поиск по сайту:
Хотим в случаях когда результат только один сразу редиректить на его страницу, минуя полу-бесполезный список:
Удивлённый пользователь — счастливый пользователь
Просто так это делать плохо: что если наш поиск нашёл совсем не того Васю Пупкина которого искал пользователь, например, если другого у нас попросту нет?
Решение: на странице с профилем Васи мы будем выводить уведомление, что у нас есть только один Вася Пупкин и на его страницу вы сейчас смотрите:
Не REST-friendly решение
Перед тем как перенапавить пользователя на страницу Васи мы пишем в сессионное хранилище признак того, что хотим показать ему уведомление.
Грубый пример на PHP:
<?php
function doRedirect($location) {
$_SESSION['show_notice'] = true;
header("Location: $location");
}
Когда показываем страницу Васи, проверяем флаг:
<?php
if (@$_SESSION['show_notice']) {
... показываем уведомление ...
}
Чем плохо такое решение?
1. Если пользователь начнёт открывать много страниц одновременно, то в зависимости от реализации может наблюдать разные интересные эффекты (мелочи по сути).
2. Если вы захотите целиком кэшировать страницы, проблемы с учётом зависимостей не заставят себя долго ждать.
1-ую проблему можно решать рядом способов, но по сути полученное хитросплетение условий и таймаутов лишний раз намекнёт на то что в сессии этой информации не место.
UPD: Кстати если вместо сессии использовать куки то вторая проблема обретает решение. Жаль что первая обостряется только сильнее :)
Чтобы обойти эти две проблемы информацию о том показывать уведомление или нет надо передавать в URL-e.
Приходим к очередному решению.
GET параметр
Тут всё просто — просто кидаем пользователя, скажем, на location/vasya/?show_notice=1:
<?php
function doRedirect($location) {
header("Location: $location?show_notice=1");
}
и при рендериге шаблона проверяем флаг:
<?php
if (@$_GET['show_notice']) {
... показываем уведомление ...
}
- Никаких глюков с одновременно открывающимися страницами.
- Можно кэшировать страницы «в лоб» по URL-у.
Самый настоящий REST и только две неприятности:
- если будем кэшировать — страница будет лежать в кэше два раза — с блоком, и без него (по сути мелочь).
- пользователи начнут давать друг другу ссылки с "?show_notice=1" — это уже не очень приятно..
document.location.hash
Ещё одно место куда можно запихнуть информацию об уведомлении это хэш.
Получится что-то вроде:
<?php
function doRedirect($location) {
header("Location: $location#show_notice");
}
тогда пользователя перебросит, например, на localhost/vasya/#show_notice
В отличие от GET параметров, сервер эту информацию попросту не получит так что показать уведомление получится только на клиенте, например, с помощью Javascript + PrototypeJS:
<div id="notice" class="notice" style="display:none">Найдена только одна страница</div>
<script type="text/javascript">
if(document.location.hash == '#show_notice')) {
$("notice").show();
document.location.hash = '';
}
</script>
Сразу после загрузки страницы localhost/vasya/#show_notice адрес сменится (без перезагрузки!) на localhost/vasya/# (назойливую решётку убрать никак не получается, но ничего страшного в ней опять же нет).