Ändern Sie die URL der Adressleiste in der AJAX-App so, dass sie dem aktuellen Status entspricht

166

Ich schreibe eine AJAX-App, aber während sich der Benutzer durch die App bewegt, möchte ich, dass die URL in der Adressleiste aktualisiert wird, obwohl keine Seiten neu geladen werden. Grundsätzlich möchte ich, dass sie jederzeit Lesezeichen setzen und damit zum aktuellen Zustand zurückkehren können.

Wie gehen Menschen mit der Aufrechterhaltung von RESTfulness in AJAX-Apps um?

jasonjwwilliams
quelle
2
Es wird verwendet, um den Status Ihrer Apps zu erhalten, hat jedoch nichts mit "RESTfulness" zu tun.
Mohamed
29
window.history.pushState(null,'hi','page1?id=32')
Omu
3
Die akzeptierte Antwort wurde vor 5 Jahren geschrieben und in der Zwischenzeit haben wir window.history.pushState bekommen, genau wie @Omu sagte. Die location.hash brachte zahlreiche Probleme und ist am besten zu vermeiden.
Pcarvalho
Ich habe die Antwort bearbeitet, um den PushState-Ansatz hervorzuheben.
Jasonjwwilliams

Antworten:

116

Die Möglichkeit hierfür besteht darin, zu manipulieren, location.hashwenn AJAX-Aktualisierungen zu einer Statusänderung führen, für die Sie eine diskrete URL wünschen. Zum Beispiel, wenn die URL Ihrer Seite lautet:

http://example.com/

Wenn eine clientseitige Funktion diesen Code ausgeführt hat:

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

location.hash = 'foo';

Dann wird die im Browser angezeigte URL aktualisiert auf:

http://example.com/#foo

Auf diese Weise können Benutzer den Status "foo" der Seite mit einem Lesezeichen versehen und mithilfe des Browserverlaufs zwischen den Status navigieren.

Wenn dieser Mechanismus vorhanden ist, müssen Sie den Hash-Teil der URL auf der Clientseite mithilfe von JavaScript analysieren, um den entsprechenden Anfangszustand zu erstellen und anzuzeigen, da Fragmentkennungen (der Teil nach dem #) nicht an die gesendet werden Server.

Das Hashchange-Plugin von Ben Alman macht letzteres zum Kinderspiel, wenn Sie jQuery verwenden.

Dave Ward
quelle
Sieht so aus, als hättest du recht. Das ist der einzige Ansatz. Dies scheint eine gute detaillierte Erklärung Ihres Ratschlags zu sein: < ajaxpatterns.org/Unique_URLs >
jasonjwwilliams
@buymeasoda Danke für die Bearbeitung; Ich bin mir nicht sicher, was ich dachte, als ich diesen Teil schrieb.
Dave Ward
1
Wow, diese Antwort war sehr hilfreich. Obwohl die URL-Beispiele etwas verwirrend sind, ersetzt SO die Links möglicherweise automatisch durch Titel. Wie wäre es, wenn Sie diese durch etwas wie example.com und example.com/#foo ersetzen, damit wir die gesamte URL im Klartext sehen können.
Neil
4
@Pascal Sie können, aber nur in Browsern, die PushState von HTML5 unterstützen. Gute Infos dazu hier: diveintohtml5.info/history.html
Dave Ward
1
Am
18

Schauen Sie sich Websites wie book.cakephp.org an. Diese Site ändert die URL ohne Verwendung des Hashs und verwendet AJAX. Ich bin mir nicht sicher, wie es genau funktioniert, aber ich habe versucht, es herauszufinden. Wenn jemand weiß, lass es mich wissen.

Auch github.com beim Betrachten einer Navigation innerhalb eines bestimmten Projekts.

daniel.wright
quelle
Ich habe das vor ungefähr einer Woche bei GitHub bemerkt. Wie um alles in der Welt machen sie das? Muss zurückgehen und nachsehen.
Drew Noakes
16
Sie scheinen die Javascript-Funktion pushState () zu verwenden. Dies fügt dem Verlauf Ihres Browsers hinzu. Schau in Es hinein; Es ist ziemlich interessant und cool.
daniel.wright
Danke dafür, es war genau das, wonach ich gesucht habe. Ich hatte mich gefragt, wie Github das gemacht hatte. Zuerst dachte ich, es muss neu geladen werden, aber es gab nur AJAX-Anfragen. In Opera wurde die Seite neu geladen.
Kamranicus
Eine ähnliche Technik wird von fb beim Navigieren durch Seiten verschiedener Gruppen verwendet. Sie haben eine linke Navigationsspalte, in der verschiedene Gruppen erwähnt werden. Wenn Sie auf einen bestimmten Gruppennamen klicken, ändert sich die URL und nur der Inhalt des Hauptinhaltsbereichs ändert sich zusammen mit der URL (kein Hash). Wenn der Benutzer die Seite neu lädt, wird er nicht zur Startseite, sondern zur Gruppenseite umgeleitet.
Madeyedexter
11

Dies ähnelt dem, was Kevin gesagt hat. Sie können Ihren Client-Status als Javascript-Objekt festlegen. Wenn Sie den Status speichern möchten, serialisieren Sie das Objekt (mithilfe der JSON- und Base64-Codierung). Sie können dann das Fragment der href auf diese Zeichenfolge setzen.

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

Der erste Weg behandelt den neuen Status als neuen Ort (so dass die Zurück-Schaltfläche sie zum vorherigen Ort bringt). Letzteres nicht.


quelle
Gibt es eine Möglichkeit, einen Eintrag zum Lesezeichenverlauf hinzuzufügen, ohne die Seite zu aktualisieren? Das Festlegen des Speicherorts (wie in Ihrem ersten Beispiel) führt zu einer Aktualisierung, nicht wahr?
Drew Noakes
Wenn Sie document.location.replace ausführen, wird der Browser auch zu dieser URL umgeleitet (habe es gerade in der Chrome-Konsole versucht)
Omu
3

SWFAddress funktioniert in Flash- und Javascript-Projekten und ermöglicht das Erstellen von Lesezeichen-URLs (unter Verwendung der oben genannten Hash-Methode) sowie die Unterstützung von Back-Buttons.

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


quelle
3

Die window.location.hash-Methode ist die bevorzugte Methode. Eine Erklärung dazu finden Sie unter Ajax-Muster - Eindeutige URLs .

YUI hat eine Implementierung dieses Musters als Modul, das IE-spezifische Problemumgehungen enthält, damit die Schaltfläche "Zurück" funktioniert und die Adresse mithilfe des Hashs neu geschrieben wird. YUI Browser History Manager .

Andere Frameworks haben ähnliche Implementierungen. Der wichtige Punkt ist, wenn Sie möchten, dass der Verlauf zusammen mit dem Umschreiben der Adresse funktioniert, benötigen die verschiedenen Browser unterschiedliche Methoden, um damit umzugehen. (Dies wird im ersten Link-Artikel beschrieben.)

IE benötigt einen iframe-basierten Hack, bei dem Firefox mit derselben Methode einen doppelten Verlauf erstellt.

Drew Noakes
quelle
3

Wenn OP oder andere noch nach einer Möglichkeit suchen, den Browserverlauf zu ändern, um den Status zu aktivieren, ist die Verwendung von pushState und replaceState, wie von IESUS vorgeschlagen, die 'richtige' Methode, dies jetzt zu tun. Der Hauptvorteil gegenüber location.hash scheint darin zu liegen, dass tatsächliche URLs erstellt werden, nicht nur Hashes. Wenn der Browserverlauf mit Hashes gespeichert und dann mit deaktiviertem Javascript erneut aufgerufen wird, funktioniert die App nicht, da die Hashes nicht an den Server gesendet werden. Wenn jedoch pushState verwendet wurde, wird die gesamte Route an den Server gesendet, den Sie erstellen können, um angemessen auf die Routen zu reagieren. Ich habe ein Beispiel gesehen, in dem sowohl auf der Server- als auch auf der Clientseite dieselben Schnurrbartvorlagen verwendet wurden. Wenn der Client Javascript aktiviert hätte, würde er schnelle Antworten erhalten, indem er den Roundtrip zum Server vermeidet. Aber die App würde ohne das Javascript einwandfrei funktionieren. Somit kann sich die App ohne Javascript elegant verschlechtern.

Ich glaube auch, dass es da draußen einen Rahmen gibt, mit einem Namen wie history.js. Für Browser, die HTML5 unterstützen, wird pushState verwendet. Wenn der Browser dies jedoch nicht unterstützt, werden automatisch Hashes verwendet.

Neil
quelle
2

Überprüfen Sie, ob sich der Benutzer auf der Seite befindet. Wenn Sie auf die URL-Leiste klicken, zeigt Javascript an, dass Sie nicht auf der Seite sind. Wenn Sie die URL-Leiste ändern und die EINGABETASTE mit dem Symbol '#' drücken, gelangen Sie erneut auf die Seite, ohne manuell mit dem Mauszeiger auf die Seite zu klicken. Anschließend wird ein Befehl für ein Tastaturereignis (document.onkeypress) aus Javascript ausgeführt Sie können überprüfen, ob es eingegeben wurde, und das Javascript für die Umleitung aktivieren. Sie können überprüfen, ob sich der Benutzer auf der Seite mit window.onfocus befindet, und überprüfen, ob er mit window.onblur nicht erreichbar ist.

Ja, das ist möglich.

;)

Marcelo
quelle
Auf diese Weise sah ich elegant, die Seite zu ändern, wenn der Benutzer die URL-Leiste mit dem Symbol # bearbeitet.
Marcelo