Zmodyfikuj adres URL paska adresu w aplikacji AJAX, aby pasował do bieżącego stanu

166

Piszę aplikację AJAX, ale gdy użytkownik porusza się po aplikacji, chciałbym, aby adres URL w pasku adresu zaktualizował się pomimo braku przeładowań strony. Zasadniczo chciałbym, aby w dowolnym momencie mogli dodać zakładkę i tym samym powrócić do obecnego stanu.

Jak ludzie radzą sobie z utrzymywaniem RESTfulness w aplikacjach AJAX?

jasonjwwilliams
źródło
2
Służy do utrzymywania stanu aplikacji, ale nie ma nic wspólnego z „RESTfulness”.
Mohamed,
29
window.history.pushState(null,'hi','page1?id=32')
Omu
3
zaakceptowana odpowiedź została napisana 5 lat temu, a tymczasem otrzymaliśmy window.history.pushState, tak jak powiedział @Omu. Lokacja location.hash przyniosła wiele problemów i najlepiej tego unikać.
pcarvalho
Zredagowałem odpowiedź, aby wyróżnić podejście pushState.
jasonjwwilliams

Odpowiedzi:

116

Aby to zrobić, należy manipulować, location.hashgdy aktualizacje AJAX powodują zmianę stanu, w którym chciałbyś mieć oddzielny adres URL. Na przykład, jeśli adres URL Twojej strony to:

http://example.com/

Jeśli funkcja po stronie klienta wykonała ten kod:

// AJAX code to display the "foo" state goes here.

location.hash = 'foo';

Następnie adres URL wyświetlany w przeglądarce zostanie zaktualizowany do:

http://example.com/#foo

Pozwala to użytkownikom na tworzenie zakładek stanu „foo” strony i używanie historii przeglądarki do przechodzenia między stanami.

Po zastosowaniu tego mechanizmu będziesz musiał przeanalizować część z krzyżykiem adresu URL po stronie klienta za pomocą JavaScript, aby utworzyć i wyświetlić odpowiedni stan początkowy, ponieważ identyfikatory fragmentów (część po znaku #) nie są wysyłane do serwer.

Wtyczka Hashchange Bena Almana sprawia, że ​​ta ostatnia jest bardzo prosta, jeśli używasz jQuery.

Dave Ward
źródło
Wygląda na to, że masz rację. To jedyne podejście. Wygląda na to, że jest to dobre szczegółowe wyjaśnienie twojej rady: < ajaxpatterns.org/Unique_URLs >
jasonjwwilliams,
@buymeasoda Dzięki za edycję; Nie jestem pewien, o czym myślałem, kiedy pisałem tę część.
Dave Ward,
1
Wow, ta odpowiedź była bardzo pomocna. Chociaż przykłady adresów URL są nieco mylące, SO może automatycznie zamieniać linki na tytuły. Co powiesz na zamianę tych na przykład.com i example.com/#foo, abyśmy mogli zobaczyć cały adres URL w postaci zwykłego tekstu.
Neil
4
@Pascal Możesz, ale tylko w przeglądarkach obsługujących pushState HTML5. Dobre informacje na ten temat tutaj: diveintohtml5.info/history.html
Dave Ward
1
Skończyło się na tym, że byłem wielkim fanem history.js, aby omówić
jocull
18

Spójrz na strony takie jak book.cakephp.org. Ta witryna zmienia adres URL bez użycia skrótu i ​​używa AJAX. Nie jestem pewien, jak to dokładnie robi, ale próbowałem to rozgryźć. Jeśli ktoś wie, daj mi znać.

Również github.com, patrząc na nawigację w ramach określonego projektu.

daniel.wright
źródło
Zauważyłem to w GitHubie około tygodnia temu. Jak oni to robią? Muszę wrócić i sprawdzić.
Drew Noakes,
16
Wydaje się, że używają funkcji javascript pushState (). To dodaje do historii Twojej przeglądarki. Spójrz na to; to jest całkiem interesujące i fajne.
daniel.wright
Dzięki za to, właśnie tego szukałem. Zastanawiałem się, jak zrobił to github. Na początku myślałem, że to musi być ponowne ładowanie, ale były tylko żądania AJAX. W przeglądarce Opera ponownie załadowała stronę.
kamranicus
Podobną technikę używa fb podczas poruszania się po stronach różnych grup. Masz lewą kolumnę nawigacyjną, w której wymienione są różne grupy. Po kliknięciu nazwy określonej grupy adres URL zmienia się i zmienia się tylko zawartość głównego panelu treści wraz z adresem URL (bez hasha). Więc kiedy użytkownik ponownie ładuje stronę, nie jest przekierowywany na stronę główną, ale na stronę grup.
Madeyedexter
11

Jest to podobne do tego, co powiedział Kevin. Możesz ustawić stan klienta jako jakiś obiekt javascript, a gdy chcesz zapisać stan, serializujesz obiekt (używając kodowania JSON i base64). Następnie możesz ustawić fragment href na ten ciąg.

var encodedState = base64(json(state));
var newLocation = oldLocationWithoutFragment + "#" + encodedState;

document.location = newLocation; // adds new entry in browser history
document.location.replace(newLocation); // replaces current entry in browser history

Pierwszy sposób potraktuje nowy stan jako nową lokalizację (więc przycisk Wstecz przeniesie ich do poprzedniej lokalizacji). Ten ostatni nie.


źródło
Czy istnieje sposób na dodanie wpisu do historii zakładek bez odświeżania strony? Ustawienie lokalizacji (jak w pierwszym przykładzie) spowoduje odświeżenie, prawda?
Drew Noakes,
wykonanie document.location.replace spowoduje również przekierowanie przeglądarki do tego adresu URL (właśnie wypróbowałem to w konsoli Chrome)
Omu
3

SWFAddress działa w projektach Flash i Javascript i umożliwia tworzenie adresów URL z zakładkami (przy użyciu wspomnianej powyżej metody haszowania), a także zapewnia obsługę przycisku wstecz.

http://www.asual.com/swfaddress/


źródło
3

Metoda window.location.hash jest preferowanym sposobem wykonywania czynności. Aby uzyskać wyjaśnienie, jak to zrobić, zobacz Wzorce Ajax - unikalne adresy URL .

YUI ma implementację tego wzorca jako moduł, który obejmuje specyficzne dla IE obejścia w celu przywrócenia działania przycisku Wstecz wraz z ponownym zapisaniem adresu przy użyciu skrótu. Menedżer historii przeglądarki YUI .

Inne frameworki również mają podobne implementacje. Ważną kwestią jest to, że jeśli chcesz, aby historia działała wraz z ponownym zapisywaniem adresu, różne przeglądarki wymagają różnych sposobów obsługi. (Jest to szczegółowo opisane w pierwszym artykule z łączem).

IE potrzebuje hackowania opartego na iframe, w którym Firefox będzie tworzył podwójną historię przy użyciu tej samej metody.

Drew Noakes
źródło
3

Jeśli OP lub inni nadal szukają sposobu na zmodyfikowanie historii przeglądarki, aby włączyć stan, użycie pushState i replaceState, zgodnie z sugestią IESUS, jest `` właściwym '' sposobem, aby to zrobić teraz. Jego główną zaletą nad location.hash wydaje się być to, że tworzy rzeczywiste adresy URL, a nie tylko skróty. Jeśli historia przeglądarki używająca skrótów zostanie zapisana, a następnie ponownie odwiedzona z wyłączoną obsługą JavaScript, aplikacja nie będzie działać, ponieważ skróty nie są wysyłane na serwer. Jeśli jednak użyto pushState, cała trasa zostanie wysłana do serwera, który można następnie zbudować, aby odpowiednio reagować na trasy. Widziałem przykład, w którym te same szablony wąsów były używane zarówno po stronie serwera, jak i klienta. Gdyby klient miał włączony javascript, otrzymywałby szybkie odpowiedzi, unikając przesyłania w obie strony do serwera, ale aplikacja działałaby doskonale bez javascript. W związku z tym aplikacja może z wdziękiem ulec degradacji w przypadku braku JavaScript.

Uważam też, że istnieje pewien framework o nazwie takiej jak history.js. W przypadku przeglądarek obsługujących HTML5 używa pushState, ale jeśli przeglądarka tego nie obsługuje, automatycznie wraca do używania skrótów.

Neil
źródło
2

Sprawdź, czy użytkownik jest „na” stronie, po kliknięciu paska adresu URL, javascript mówi, że nie ma Cię na stronie. Jeśli zmienisz pasek adresu URL i naciśniesz „ENTER” z symbolem „#”, a następnie przejdziesz do strony, bez ręcznego klikania strony kursorem myszy, wówczas polecenie zdarzenia klawiatury (document.onkeypress) z javascript będzie być w stanie sprawdzić, czy wpisuje i aktywuje javascript do przekierowania. Możesz sprawdzić, czy użytkownik jest NA stronie z window.onfocus i sprawdzić, czy nie ma go za pomocą window.onblur.

Tak, to możliwe.

;)

Marcelo
źródło
W ten sposób uważam, że zmiana strony jest elegancka, gdy użytkownik edytuje pasek adresu URL z symbolem #.
Marcelo