Comments 58
Хм, сперва полагал, что речь идёт о юзабилити-примерах, а тут программирование. Было бы неплохо пояснить, о чём речь в статье далее до ката.
Спасибо.
Спасибо.
Про хэш не задумывался даже. Между сессием и get-параметром выбрал сессию. Может позже на хэш переделаю. Спасибо
а я вот от сессии отказался из за кеширования, пользовался гетом, но соответственно баги при возврате по хистори
хэш действительно хороший вариант
хэш действительно хороший вариант
Можно еще куку вешать.
Ее уже можно и из js проверять и на стороне сервера, в зависимости от задачи.
Ее уже можно и из js проверять и на стороне сервера, в зависимости от задачи.
с кукой есть проблемы примерно как с сессией, только более ярко выраженные,
например если куку снимать при показе страницы после редиректа, то если странице не дать открыться, — уведомление вылезет уже позже в неподходящем случае
например если куку снимать при показе страницы после редиректа, то если странице не дать открыться, — уведомление вылезет уже позже в неподходящем случае
Куку можно вешать с очень маленьким ttl и/или уникальную для страницы, например со значением урала самой страницы.
Перекуем мечи на урала! =)
куку нужно вешать с такой областью видимости чтобы она только на целевой странице и была доступна. с маленьким TTL это решит вопрос с «запоздалым проявлением», а если в ней передавать «идентификатор сообщения» (которые хранятся отдельно) то это решит и проблемы одновременным открытием нескольких страниц с разыми сообщениями.
где холивар насчет того, что у пользователя JS отключен? :)
Для борьбы с открытием нескольких окон — кто мешает сохранять более полные данные в сессии? Не только сам факт редиректа (show_notice=1), но и адрес страницы, куда перекидывается юзер (location=$location)? Если откроет несколько страниц — нотификашка покажется только на той, у которой совпадает URI.
А если при открытии окна сразу убирать обе переменные из сессии — тогда вообще даже при повторном открытии окна (по F5) ничего не покажется.
А если при открытии окна сразу убирать обе переменные из сессии — тогда вообще даже при повторном открытии окна (по F5) ничего не покажется.
Это тоже не панацея :) (для кук в большей степени, для сессии это надо умудрится, но теоретически тоже можно)
1. меня кидает на /a.php
2. я не даю ей загрузится (тупо кликаю по закладке и ухожу в другое место), т.е. JS-ы которые удалят куки не выполняются
3. гуляю по сайту, захожу на /a.php — и вижу уведомление. не очень к месту :)
Это можно лечить таймаутами — но опять же, на глючном GPRS-е страница может 30 секунд запросто грузиться. А для быстрого интернета за 30 секунд вполне можно вопсроизвести описанный ранее глюк :)
Если чесно, все эти заморочки не стоят своей разработки.
Да и проблемы при использовании сессии или кук появляются как раз от того что это неподходящее место для такой информации.
1. меня кидает на /a.php
2. я не даю ей загрузится (тупо кликаю по закладке и ухожу в другое место), т.е. JS-ы которые удалят куки не выполняются
3. гуляю по сайту, захожу на /a.php — и вижу уведомление. не очень к месту :)
Это можно лечить таймаутами — но опять же, на глючном GPRS-е страница может 30 секунд запросто грузиться. А для быстрого интернета за 30 секунд вполне можно вопсроизвести описанный ранее глюк :)
Если чесно, все эти заморочки не стоят своей разработки.
Да и проблемы при использовании сессии или кук появляются как раз от того что это неподходящее место для такой информации.
Погоди, при чем здесь JS? Наверное слово «окно» сбило с толку… Я говорю о выполнении этих вещей на сервере. Идет запрос на открытие страницы (шлются заголовки от браузера), PHP-парсер отрабатывает страницу, видит из переменных сессии, что стоит редирект на вызываемую страницу. Ну и далее — он сначала убирает 2 теперь уже лишние переменные из сессии и выдает страниы с примечанием наверху. Всё, при следующем обращении на эту же страницу ничего не показывается. При обращении на соседние страницы оно в принципе не отобразится — поскольку мы запомнили, куда именно надо показать инфу.
ну да, всё правильно, с сессией на практике всё сильно лучше чем с куками (хотя логически проблемы те же)
Мне просто по жизни механизм кэширование мешает пользоваться сессией, и я её как-то мысленно всё время отбрасываю.
Хотя когда такой проблемы нет, сессия и без лишних заморочек отлично справляется — очень удобно, — можно в любом месте кода добавлять туда уведомления и не думать когда произойдёт редирект.
Мне просто по жизни механизм кэширование мешает пользоваться сессией, и я её как-то мысленно всё время отбрасываю.
Хотя когда такой проблемы нет, сессия и без лишних заморочек отлично справляется — очень удобно, — можно в любом месте кода добавлять туда уведомления и не думать когда произойдёт редирект.
Чем пользуешься для кеширования? Кеширование ведь надо параметризовывать — хотя бы для того, чтобы не отдавать одну и ту же инфу залогинены пользователям и гостям.
всё самописное, и с параметризацией всё порядке.
проблема, как я сейчас вспомнил, была немного хитрее — у меня поиск кэшировал редирект на страницу с результатом, — т.е. при попадании в кэш редирект происходил, а вот в сессию сообщение уже никто не писал, решение сохранять вместе с редиректом часть сессии показалось уж слишком странным, — тут-то и начались изыскания :)
проблема, как я сейчас вспомнил, была немного хитрее — у меня поиск кэшировал редирект на страницу с результатом, — т.е. при попадании в кэш редирект происходил, а вот в сессию сообщение уже никто не писал, решение сохранять вместе с редиректом часть сессии показалось уж слишком странным, — тут-то и начались изыскания :)
Не совсем понял, что значит «кешировал редирект»? Ты делаешь поиск по базе, получаешь данные, и на основании того, что в этих данных только 1 запись — делаешь редирект. Так ведь? Где в этой цепочке кеш?
Кэширование идёт на самом верхнем уровне, до поиска
1. приходит запрос /search?q=вася
2. я к нему дописываю зависимости (например признак того что это страница для гостя)
3. смотрю нет ли чего у меня в кэше по такому запросу,
4. и не лазя в базу отдаю редирект
1. приходит запрос /search?q=вася
2. я к нему дописываю зависимости (например признак того что это страница для гостя)
3. смотрю нет ли чего у меня в кэше по такому запросу,
4. и не лазя в базу отдаю редирект
А никто не задумывался, что подобная проблема (notice'ы) возникает только если движок криво оперирует данными?
Я имею ввиду, например когда у программиста нет возможности на самой странице результатов поиска написать что-то типа:
if (только один вариант) {
показать(notice);
обработать_и_показать(только один вариант);
} else {
показать все результаты поиска;
}
и не будет проблем с никакими редиректами типа header:Location или document.location.
Я имею ввиду, например когда у программиста нет возможности на самой странице результатов поиска написать что-то типа:
if (только один вариант) {
показать(notice);
обработать_и_показать(только один вариант);
} else {
показать все результаты поиска;
}
и не будет проблем с никакими редиректами типа header:Location или document.location.
я правильно понимаю что предлагается по урлу поиска ( например localhost/search? параметры) показывать найденную страницу?
на мой вкус это не хорошо хотя бы тем что нельзя дать нормальную ссылку на эту страницу,
всё таки если в результате поиска находится страница про Васю, то и отображатся она должна по соответствующему URL-у: например localhost/pages/Вася
на мой вкус это не хорошо хотя бы тем что нельзя дать нормальную ссылку на эту страницу,
всё таки если в результате поиска находится страница про Васю, то и отображатся она должна по соответствующему URL-у: например localhost/pages/Вася
Эк мы с тобой одновременно светлые мысли кидаем… :)))
Если с точки публичного поиска — то да, Вы правы.
Но если поиск внутри, например, админ-панели, то помоему намного лучше избавляться от любых редиректов любыми силами.
Насчет того, что нельзя дать URL на страницу результатов — неправда, можно. Сомневаюсь что параметры в запрос поиска Вы будете передавать POSTом :)
Но если поиск внутри, например, админ-панели, то помоему намного лучше избавляться от любых редиректов любыми силами.
Насчет того, что нельзя дать URL на страницу результатов — неправда, можно. Сомневаюсь что параметры в запрос поиска Вы будете передавать POSTом :)
Часто бывает, что за поиск данных и за их отображение отвечают разные модули системы. В этом слуае при поиске проще обработать количество найденного и переправить посредством стандартного заголовка HTTP.
Есть и более прозаическая причина — ЧПУ (ЧеловекоПонятныйУрл). У поиска и у конкретной страницы с данными разные урлы. Соответственно, если статья о Пупкине лежит по адресу site.com/people/pupkin/, то урл поиска — по адресу site.com/search/?subj=Пупкин. Выдавать одну и ту же страницу (про Васисуалия) по двум разным урлам — это не совсем правильно. Почему неправильно — есть разные причины, это тема отдельного большого топика.
Есть и более прозаическая причина — ЧПУ (ЧеловекоПонятныйУрл). У поиска и у конкретной страницы с данными разные урлы. Соответственно, если статья о Пупкине лежит по адресу site.com/people/pupkin/, то урл поиска — по адресу site.com/search/?subj=Пупкин. Выдавать одну и ту же страницу (про Васисуалия) по двум разным урлам — это не совсем правильно. Почему неправильно — есть разные причины, это тема отдельного большого топика.
Ответил выше.
Насчет разных модулей системы и того, что Вы не можете из одного модуля вызвать инициализацию другого — ну это явно же проблема движка (а точнее его отсутствия).
Хотя, даже если поиск доступен публике (поисковому боту). Я не уверен что он так просто в строку поиска введет «Вася пупкин» и получит вторую страницу идентичную ЧПУ Пупкину. И если Вы даже светите ссылку на site.com/search/?subj=Пупкин — что мешает Вам добавить во время поиска:
link rel=«canonical» href=«hvosting.ua/hosting.html»
или вообще закрыть к индексации /search/*
Насчет разных модулей системы и того, что Вы не можете из одного модуля вызвать инициализацию другого — ну это явно же проблема движка (а точнее его отсутствия).
Хотя, даже если поиск доступен публике (поисковому боту). Я не уверен что он так просто в строку поиска введет «Вася пупкин» и получит вторую страницу идентичную ЧПУ Пупкину. И если Вы даже светите ссылку на site.com/search/?subj=Пупкин — что мешает Вам добавить во время поиска:
link rel=«canonical» href=«hvosting.ua/hosting.html»
или вообще закрыть к индексации /search/*
Про инициализацию — никто не говорит, что нельзя вызвать один из другого. Нормальная система сможет это сделать легко. Вопрос в нагромождении взаимных вызовов и, как следствие, усложнение логики, появление нетривиальных ошибок «на стыке» модулей.
Мой point в том, что поведение системы не должно быть сложным. Отработал модуль — выдал результат. В нашем случае результат — одна ссылка. И мы за пользователя просто делаем следующий шаг — «нажимаем» на ссылку и попадаем куда надо. Так вот это «нажатие» не должно происходить посреди алгоритмов и вызовов. Чем ближе «к поверхности», тем проще.
Насчет УРЛов — xnj tcnm URI (URL) — Unified Resource Identifier (Locator). Т.е. это унифицированное ID ресурса. Есть ресурс — страница о В. Пупкине — у него должен быть унифицированный (и, по возможности, уникальный) идентификатор. А так получится большое множество — по числу вариантов нахождения странице о Васе.
Хотя по этому пункту не буду настаивать — это полу-религиозный вопрос :)
Мой point в том, что поведение системы не должно быть сложным. Отработал модуль — выдал результат. В нашем случае результат — одна ссылка. И мы за пользователя просто делаем следующий шаг — «нажимаем» на ссылку и попадаем куда надо. Так вот это «нажатие» не должно происходить посреди алгоритмов и вызовов. Чем ближе «к поверхности», тем проще.
Насчет УРЛов — xnj tcnm URI (URL) — Unified Resource Identifier (Locator). Т.е. это унифицированное ID ресурса. Есть ресурс — страница о В. Пупкине — у него должен быть унифицированный (и, по возможности, уникальный) идентификатор. А так получится большое множество — по числу вариантов нахождения странице о Васе.
Хотя по этому пункту не буду настаивать — это полу-религиозный вопрос :)
Я использую тоглько 2й вариант (1й — муть, а 3й требует яваскрипта который нафиг не вперся ради такой мелочи). Только передавать удобее не цифры и ид, например: Location: /login.php?msg=need_login
Второй вариант проигрывает 3-му тем что пользователи начинают друг-другу давать ссылки на страницы с открытым уведомлением, хотя сторонним людям оно нафиг не упало ( пример: moikrug.ru/companies/571544408/?one=1 ). Но эта проблема не касается страниц на которые ссылок не дают ( ну например внутренние страницы какой-нибудь админки )
1-й вариант очень удобен как универсальное решение для всего сайта, могу объяснить почему если интересно
1-й вариант очень удобен как универсальное решение для всего сайта, могу объяснить почему если интересно
Насчет ссылок — да, тоже верно (( Тогда предлагаю дополнительно ставить короткоживущую куку к ссылке (просто кука — не совместима с открытием страницы в нескольких окнах параллельно).
А заводить ради этого сессию считаю неразумным все же.
> 1-й вариант очень удобен как универсальное решение для всего сайта, могу объяснить почему если интересно
Конечно интересно, попробуйте :)
А заводить ради этого сессию считаю неразумным все же.
> 1-й вариант очень удобен как универсальное решение для всего сайта, могу объяснить почему если интересно
Конечно интересно, попробуйте :)
Мне кажется не совсем правильным перенаправлять пользователя на страницу Васи, даже если он всего один такой. Почему? Потому что это нарушает ожидания пользователя — он возможно просто хотел проверить файт наличия Васи (и число этих Вась), а не получать целую статью с картинками про него — зачем его заваливать бесполезной информацией. То есть мне кажется, это весьма спорное решение и подходит не везде и не всем…
Да, конечно, это довольно редкий случай когда имеет смысл так делать.
Собственно я и выбрал этот пример для статьи о нотификациях, потому что в нём без нотификатора ну никак не обойтись.
Спасибо.
Собственно я и выбрал этот пример для статьи о нотификациях, потому что в нём без нотификатора ну никак не обойтись.
Спасибо.
В этом и суть уведомлений в данном примере — показать, что это уже не страница поиска, что система решила упростить жизнь пользователю, но он может вернуться.
Если вы не делаете перенаправлений, то и уведомления вам не нужны.
Если вы не делаете перенаправлений, то и уведомления вам не нужны.
Мне кажется не совсем правильным перенаправлять пользователя на страницу Васи, даже если он всего один такой
А я бы сказал что редко когда это неправильно.
К примеру, на «каталогах» меня напрягает то, что я *точно* знаю что мне надо, я ищу это, а получаю страницу результатов. Например, ищем «после прочтения сжечь». В данном случае релевантность первой записи более чем гигантская, всё остальное очевидно не подходит даже для сравнения.
Могу предложить ещё такое извращение — использовать 2-й способ, но при загрузке делать редирект на страницу без мусорного параметра, а на ней смотреть REFERER =)
Устранены все проблемы, кроме F5.
Я использую сессии.
Устранены все проблемы, кроме F5.
Я использую сессии.
«пользователи начнут давать друг другу ссылки с »?show_notice=1" — это уже не очень приятно"
надо HTTP_REFERER && show_notice проверять
тогда эта проблема исчезает
надо HTTP_REFERER && show_notice проверять
тогда эта проблема исчезает
я бы выбрал вариант с cookie.
сессия для каждого пользователя — слишком дорогое удовольствие для высоконагруженных проектов.
$_GET не очень удобен в смысле шаринга ссылок и рефреша страницы
javascript здесь не кажется идеологически верным вариантом (всё же он отвечает за поведение элементов на странице, а не их состав).
сессия для каждого пользователя — слишком дорогое удовольствие для высоконагруженных проектов.
$_GET не очень удобен в смысле шаринга ссылок и рефреша страницы
javascript здесь не кажется идеологически верным вариантом (всё же он отвечает за поведение элементов на странице, а не их состав).
Я почему-то думал, что в статье будет приведен такой пример:
function doRedirect($location) { header("X-Show-Notice: show"); header("Location: $location"); }
X-Show-Notice: show
Будет выдано браузеру. Стало быть, обработку этого сообщения надо сделать силами, опять же, браузера. Можете привести работу JS-срипта для обработки этого заголовка?
Будет выдано браузеру. Стало быть, обработку этого сообщения надо сделать силами, опять же, браузера. Можете привести работу JS-срипта для обработки этого заголовка?
В подобной ситуации всегда пользовался модифицированным первым вариантом. Причём в $_SESSION['messages'] хранится массив вида: ('/news/253/'=>'Новость успешно добавлена') (не знаю как и зачем передавать просто флаг о сообщении, причём непоятно о каком). В нужном месте проверить текущий url на присутствие в messages, вывести и удалить url из массива в сессии. Всё просто. На сервере сразу будет видно, что результат поиска один и что будем редиректить сразу на /Вася_Пупкин/, следовательно запись такая: ('/Вася_Пупкин/'=>'Нашлась только.....').
А в js втюхивать что-то — рука не подымится. А отключенный js? А i18n? Да и мороки больше. Можно, конечно, при желании генерировать нужный js-словарь сообщений при обращении, но это уже другая тема.
А в js втюхивать что-то — рука не подымится. А отключенный js? А i18n? Да и мороки больше. Можно, конечно, при желании генерировать нужный js-словарь сообщений при обращении, но это уже другая тема.
мне кажется, если не самый легкий, то самый прямой (с наименьшим количеством костылей) вариант хранить нотификации в бд, да, данные будут пухнуть, но с этим можно что-то придумать Т.е. объекты системы могут нотифаить пользователю, а сам нотификатор забирает сообщения из базы и показывает, при этом выбранные к показу собщения можно либо сразу удалять из бд, либо ставить флажок «прочитано». С таким подходом мы обретаем и несколько дополнительных возможностей, например, нотификации, которые показываться до выполнения определенного условия (например «заполните номер телефона в профиле», «подтвердите введенный емейл»:) или в определенное время (можно повесить нотификацию которую пользователь должен будет увидеть через месяц).
а для гостя как сообщения к пользователю привязывать? по id сессии? тогда это и есть просто сессия, которая хранится в БД :)
у автора очень простой пример, случаев когда полезно захардкодить сообщения прямо в шаблон/код можно придумать не много. Поэтому предложенное решение скорее костыль для такой вот конкретной ситуации. А когда вам надо передать сообщений 5-10 или чтото более контекстнозависимое изобразить, то я думаю такой вариант не подойдет
пример описывает частый случай нагруженной гостевой страницы на которой обязательно должно быть кэширование, которое плохо уживается с передачей сообщений через сессию (можно, но страшно костыльно).
Кстати не обязательно делать сообщения предвбитыми, на JS вполне можно сделать схему не менее гибкую чем на базе сессии в PHP.
5-10 сообщений могут вылезти только в каком-нибудь внутреннем залогиновом интерфейсе, тут безусловно удобнее делать реализацию через сессию например как в Codeigniter::Flashdata.
Кстати не обязательно делать сообщения предвбитыми, на JS вполне можно сделать схему не менее гибкую чем на базе сессии в PHP.
5-10 сообщений могут вылезти только в каком-нибудь внутреннем залогиновом интерфейсе, тут безусловно удобнее делать реализацию через сессию например как в Codeigniter::Flashdata.
Sign up to leave a comment.
Техническая реализация REST & user friendly уведомлений после редиректов