Jakiś czas temu znalazłem u Piotra Sajnoga wpis o WordPressowej wtyczce Comment Redirect, pozwalającej na wyświetlenie po dodaniu przez użytkownika pierwszego komentarza na blogu strony z podziękowaniem [i zachętą do dalszej współpracy ;]]. Zostawiła tam komentarz także Banny, która zdecydowała się przetestować jej [tej wtyczki ;]] działanie także u siebie, gdzie miałem okazję pierwszy raz zetknąć się od strony użytkownika z tytułowym przekierowaniem. Zauważyłem jednak, że po dodaniu komentarza musiałem sam zatroszczyć się o „nawigację wstecz” do wpisu, ponieważ strona nie zawierała ani elementu meta refresh, ani żadnej innej JavaScriptowej metody przeniesienia na poprzednią stronę. Zasugerowałem więc w jednym z komentarzy, żeby umieściła w kodzie tej strony „coś”, co pozwoli na wygodniejsze korzystanie z tej strony. Ze względu na to, że nie zajmuje się ona programowaniem, z miejsca zostałem poproszony o pomoc.
Kobietom się nie odmawia, dlatego oczywiście zgodziłem się na „wydłubanie” jakiegoś rozwiązania. Trochę to niestety trwało, częściowo przez moje zapominalstwo, a częściowo przez zbliżające się zaliczenia, do których niestety musiałem się przygotować, ale w końcu udało się. Chwilę się nad tym wszystkim zastanawiałem i stwierdziłem, że fajnie byłoby przedyskutować inne sposoby umożliwiania w takim wypadku użytkownikowi powrotu na poprzednią stronę, tak, aby można było wybrać optymalną dla siebie metodę. Zapraszam do lektury.
Wstęp.
Tradycyjnie mamy kilka możliwości na skierowanie użytkownika do odpowiedniego miejsca na naszej witrynie – zarówno po stronie klienta, jak i wspomagając się nieco technologiami po stronie serwera. Mamy zatem metody:
- JavaScript
- Obiekt History
- Metoda go()
- Metoda back()
- Document.referrer
- Obiekt History
- PHP
W niniejszym wpisie przedstawię sposoby opierające się na kliknięciu przez użytkownika odpowiedniego linku powrotnego, ponieważ zakładam, że na aktualnej stronie, tak jak w przypadku wtyczki Comment Redirect, znajduje się treść, z którą użytkownik powinien się zapoznać, zanim opuści daną podstronę. Myślę, że przekształcenie tego kodu w automatycznie przekierowanie nie będzie dla Was zbyt trudne, w razie czego oczywiście służę pomocą. ;]
JavaScript.
Pierwszy na warsztat idzie oczywiście JavaScript jako rozwiązanie typowe, nie wymagające angażowania serwera w proces generowania informacji o tym, skąd przybył użytkownik, a opierające się wyłącznie na „wewnętrznych” danych przeglądarki.
Obiekt History
Obiekt History, jak sama nazwa wskazuje, pozwala na nawigację po historii przeglądarki użytkownika. Posiada ona kilka metod, z których dwie mogą zostać użyte do nawigacji wstecz:
* Metoda go()
Metoda go() przyjmuje jeden parametr [liczbę całkowitą lub string] będący relatywnym położeniem aktualnej strony w historii od tej, na którą chcemy przejść. Jak nietrudno się domyślić – aby przejść wstecz, należy podać ujemną wartość wymaganego parametru. Zatem kod wynikowy będzie wyglądał następująco [przechodzimy na poprzednią stronę historii]:
<a href="javascript: history.go(-1)">Powrót do wpisu.</a>
* Metoda back()
Prostszym sposobem niż użycie metody go() z parametrem -1 będzie wykorzystanie metody back(), która robi to automatycznie:
<a href="javascript: history.back()">Powrót do wpisu.</a>
Document.referrer
Mamy też oczywiście możliwość manualnego przejścia do strony, która nas „odesłała” – wykorzystamy zatem atrybut referrer obiektu Document, który zawiera URL strony odsyłającej.
<a href="javascript: window.location.href=document.referrer">Powrót do wpisu.</a>
To tyle w kwestii JavaScriptu, zobaczmy co ma do pokazania strona serwera. ;]
PHP.
$_SERVER['HTTP_REFERER']
Strona serwera ma tu akurat niewiele do powiedzenia – wykorzystujemy ją tylko do pobrania adresu URL, z którego przybył nasz wspaniały użytkownik, a reszta mechanizmu jest już tradycyjna:
<a href="javascript: window.location.href='<?php echo $_SERVER['HTTP_REFERER'] ?>'">Powrót do wpisu.</a>
Zaletą tego rozwiązania jest to, że możemy w sposób niewidoczny dla użytkownika dokonać sprawdzenia skąd przybył i w przypadku, kiedy np. jest to jedna ze stron potencjalnie niebezpiecznych, mamy możliwość podania innego linka niż ten, który został domyślnie zapisany.
Podsumowanie.
Zdaję sobie sprawę z tego, że liczba sposobów i pomysłów na przeniesienie użytkownika do określonego miejsca w Internecie jest na pewno większa niż zakres zmiennej typu unsigned int w każdym cywilizowanym kompilatorze, ale i tak mam nadzieję, że przyda się Wam takie krótkie podsumowanie. Jeśli macie swoje [inne niż wymienione] ulubione sposoby na udostępnianie tego typu funkcjonalności, podzielcie się w komentarzach, a nuż czegoś się [znowu] nauczę? ;]
PS. Przepraszam za tą dwutygodniową przerwę we wpisach, na swoje usprawiedliwienie mogę jedynie powiedzieć, że przynajmniej zaliczyłem wszystko. Niestety w kolejnym tygodniu nie będę miał dostępu do komputera, więc niestety oznacza to kolejny przestój, ale już 15 lutego będę z powrotem i obiecuję pisać [w miarę] regularnie. ;]
Warto przeczytać.
Trwa ładowanie…
A ja jeszcze raz dziękuję za pomoc… :) Pytanie mam: z punktu widzenia administratora i użytkownika, lepszy będzie JV czy php? :)
Nie ma za co. ;] Tutaj nie bardzo można rozdzielić oba „punkty widzenia”, ponieważ tak, czy inaczej używamy JavaScriptu do samego „przeładowania” strony. Strona klienta, czyli sam JS to prostota i wygoda – jedna linijka i po sprawie, tak więc w Twoim przypadku będzie lepsza. Strona serwera pozwala na większą kontrolę i kombinowanie poza oczami użytkownika – dostaje on po prostu link do „jakiejś” strony, np. jak przyszedł z google.com, to dajemy mu powrót do naszej „głównej”, zawsze jedna odsłona więcej ;] – po stronie klienta takie modyfikacje musimy umieszczać w widocznych skryptach JS.
Na referer bym uważał, bo można sobie krzywdę zrobić ^^ Np. jeśli taka podstrona, zostanie z jakiegoś powodu umieszczona w iframie, efektem kliknięcia linku, może być załadowanie strony nadrzędnej, bo ona się może znajdować w refferer. back w najgorszym przypadku nie zrobi po prostu nic.
Z punktu widzenia elastyczności też wygrywa back. Np. jeśli strona będzie w ajax, to back można przechwycić i załadować poprzednią stronę za pomocą ajax. W drugim przypadku dostanie się przeładowanie strony.
Najlepszym rozwiązaniem będzie samodzielne przetestowanie. ;] Wykonałem trzy stronki: jedną demonstrującą wszystkie cztery przekierowania, drugą z elementem iframe wskazującym na pierwszą i trzecią z linkiem do drugiej. Efekt jest następujący:
* go(-1) i back() prowadzą do strony z linkiem [poprawnie]
* document.referer i $_SERVER['HTTP_REFERER'] ładuje ponownie do iframe zawartość drugiej stronki [po kliku kliknięciach mamy kilka zagnieżdżonych ramek] – czyli błąd.
Dzięki za konstruktywną krytykę. ;]
A ja zrobiłbym w taki sposób:
<a href="” title=”Powrót do poprzedniej strony” class=”history-back”>
I w pliku ze skryptami (przykład dla jQuery):
$(‚a.history-back’).click(function(e) {
history.back();
e.preventDefault();
});
Czy dla czystego JS:
var i, link = document.getElementsByTagName(‚a’);
for (i=0; i<link.length; i++) {
if (link[i].className.search('history-back') != -1)
link[i].onclick = function() {return history.back()};
}
Myślę, że to rozwiązanie jest najbardziej optymalne. Dobre dla wyszukiwarek, dobre dla przeglądarek bez JS, no i użyteczne.
btw. w href linku powinno być $_SERVER['HTTP_REFERER'], ale wordpress wywaliło gdy obudowałem w znaczniki PHP :-)
Ciekawą alternatywą jest zastosowanie przerobionej wtyczki, napisanej przez Łukasza Więcka – sposób, opisany na jego blogu łączy moim zdaniem prostotę konfiguracji (jak w JS) z potęgą PHP… ;)
Wiesz, to było rozwiązanie dla pojedynczego linka, tak jak to opisałem we wstępie, ale faktycznie, w przypadku kiedy chcielibyśmy hurtowo podpiąć powroty do poprzedniej strony to Twój sposób jest całkiem ok. ;]
Wyczuwam tutaj jakieś nieuzasadnione uprzedzenia do języka PHP, spokojnie, nie jest taki zły… ;]
Co do samego rozwiązania to nie jest ono złe, ale jak widać poradziłem sobie z problemem w prostszy sposób. ;]
Tomek, mam takie pytanie. Nie wiesz jaki skrypt jest odpowiedzialny np. na smashingmagazine.com za taką sytuację: Czytam długi artykuł, przerywam czytanie w określonym punkcie, wychodzę ze strony, ale do niej wracam (do tego samego artykułu) i zostaję od razu przerzucony do miejsca w jakim skończyłem czytać, nim opuściłem site???
Myślę, że to nie jest skrypt, tylko funkcjonalność przeglądarki, która po prostu pamięta układ odwiedzanych stron w jakim zostały zamknięte. Jeśli mówimy o Firefoksie, to wydaje mi się to całkiem prawdopodobne, bo wiele razy zauważałem takie zachowanie, po pewnym czasie nawet przyzwyczaiłem się do tego, że jestem od razu przenoszony do odpowiedniego miejsca.
Muszę coś z tym zrobić, bo już w kilku komentarzach „ucięło” niepotrzebnie kawałek kodu.
Dzięki, przydało się do mojej inżynierki.
no i jak masz ssl to nie ma http_referer
@usher: Cieszę się. :)
@Rafał: Dzięki za informacje, na pewno przyda się Czytelnikom. :)
CodeRetreat 2011: Na miejsca, gotów…