Wie ändere ich die URL, ohne die Seite neu zu laden?

2377

Gibt es eine Möglichkeit, die URL der aktuellen Seite zu ändern, ohne die Seite neu zu laden?

Ich möchte, wenn möglich, vor dem # Hash auf den Teil zugreifen .

Ich muss nur den Teil nach der Domain ändern , damit ich nicht gegen domänenübergreifende Richtlinien verstoße.

 window.location.href = "www.mysite.com/page2.php";  // Sadly this reloads
Der Blitz
quelle
139
Um das Verständnis der Frage zu erleichtern, macht Facebook dies beispielsweise, wenn Sie ein Foto öffnen. Die URL-Leiste ändert sich so, dass sie DIREKT auf dieses Foto verweist, sodass Sie die URL freigeben können, ohne zu verlieren, wo Sie sich auf der Website befinden. Erinnern Sie sich an Websites, die auf Framing im letzten Jahrzehnt basieren? Sie konnten nur die Homepage-URL abrufen, da sich nur interne Frames änderten. Und das war schrecklich.
Spidey
Während dies history.pushState()hier wahrscheinlich die richtige Antwort ist, sollten Sie in dieser Situation (abhängig von den genauen Umständen ...) die Möglichkeit einer serverseitigen Umleitung (z. B. über die Verwendung der RewriteRule-Direktive von Apache) in Betracht ziehen, oder zumindest sei dir bewusst. Ich dachte nur, es sollte erwähnt werden!
Doin

Antworten:

2033

Dies ist jetzt in Chrome, Safari, Firefox 4+ und Internet Explorer 10pp4 + möglich!

Weitere Informationen finden Sie in der Antwort dieser Frage: Aktualisieren der Adressleiste mit einer neuen URL ohne Hash oder erneutes Laden der Seite

Beispiel:

 function processAjaxData(response, urlPath){
     document.getElementById("content").innerHTML = response.html;
     document.title = response.pageTitle;
     window.history.pushState({"html":response.html,"pageTitle":response.pageTitle},"", urlPath);
 }

Sie können dann die window.onpopstateNavigation der Zurück / Vorwärts-Taste erkennen:

window.onpopstate = function(e){
    if(e.state){
        document.getElementById("content").innerHTML = e.state.html;
        document.title = e.state.pageTitle;
    }
};

Weitere Informationen zum Bearbeiten des Browserverlaufs finden Sie in diesem MDN-Artikel .

David Murdoch
quelle
272
Wie macht Facebook das dann in IE7?
Dominic
57
@CHiRiLo check out history.js , das einen Fallback für Browser bietet, die die HTML5-Verlaufs-API nicht unterstützen.
David Murdoch
23
@infensus Wenn es irgendwo ein # -Zeichen in der URL gibt, gibt es diesen Trick seit Jahren .
Izkata
34
Was bedeutet der "pp4 +" - Teil von "IE10pp4 +"?
Scott Tesler
34
Plattform Vorschau 4
David Murdoch
587

In HTML5 wurden die Methoden history.pushState()und eingeführt history.replaceState(), mit denen Sie Verlaufseinträge hinzufügen bzw. ändern können.

window.history.pushState('page2', 'Title', '/page2.php');

Lesen Sie mehr über diese von hier

Vivart
quelle
12
Funktioniert möglicherweise file:///aus Sicherheitsgründen nicht, z. B. Firefox 30. Testen Sie localhostmit python -m SimpleHTTPServer.
Ciro Santilli 法轮功 病毒 审查 六四 事件 9
6
Es wird erwartet, dass der erste Parameter ein Objekt ist, nicht nur eine Zeichenfolge.
Alexis Wilke
40
IMO das ist wirklich die beste Antwort. Wenn Sie nur die aktuelle URL ({}, null, strNewPath) aktualisieren möchten, müssen Sie dies nur tun. Am besten zuerst mit if (history.pushState) {} testen
Craig Jacobs
7
Sie können für die ersten beiden Parameter einfach null eingeben, wenn Sie sie nicht ändern möchten. Sie können auch eine absolute URL für den dritten Parameter verwenden.
Andrew
3
Es wäre schön, wenn Sie weitere Informationen nur in die Antwort einfügen würden. Ich habe keine Ahnung, was Parameter 1 macht.
RedClover
130

Sie können auch HTML5 replaceState verwenden, wenn Sie die URL ändern möchten, aber den Eintrag nicht zum Browserverlauf hinzufügen möchten:

if (window.history.replaceState) {
   //prevents browser from storing history with each change:
   window.history.replaceState(statedata, title, url);
}

Dies würde die Funktionalität der Zurück-Schaltfläche "unterbrechen". Dies kann in einigen Fällen erforderlich sein, z. B. in einer Bildergalerie (in der die Schaltfläche "Zurück" zur Indexseite der Galerie zurückkehren soll, anstatt sich durch jedes einzelne angezeigte Bild zu bewegen), während jedem Bild eine eigene URL zugewiesen wird.

George Filippakos
quelle
110

Hier ist meine Lösung (newUrl ist Ihre neue URL, die Sie durch die aktuelle ersetzen möchten):

history.pushState({}, null, newUrl);
Haimei
quelle
1
Am besten zuerst mit if (history.pushState) {} testen. Nur für den Fall eines alten Browsers.
Craig Jacobs
Dies funktioniert nicht mehr in Firefox: Der Vorgang ist unsicher.
kkatusic
Und der Benutzer kann mit diesem Ansatz sogar ein Lesezeichen setzen, wunderschön! Ich kann jetzt die URL bei Benutzereingaben aktualisieren und er kann alle seine Einstellungen direkt mit einem Lesezeichen versehen.
Codepleb vor
107

HINWEIS: Wenn Sie mit einem HTML5-Browser arbeiten, sollten Sie diese Antwort ignorieren. Dies ist jetzt möglich, wie aus den anderen Antworten hervorgeht.

Es gibt keine Möglichkeit, die URL im Browser zu ändern, ohne die Seite neu zu laden. Die URL gibt an, wie die zuletzt geladene Seite war. Wenn Sie es ändern ( document.location), wird die Seite neu geladen.

Ein offensichtlicher Grund ist, dass Sie eine Site schreiben www.mysite.com, die wie eine Bank-Anmeldeseite aussieht. Dann ändern Sie die URL-Leiste des Browsers www.mybank.com. Der Benutzer wird überhaupt nicht wissen, dass er wirklich schaut www.mysite.com.

Robin Day
quelle
33
Ich möchte die Domain nicht ändern, nur den Pfad und den Dateinamen.
TheFlash
5
Dies stoppt potenzielle Sicherheitsrisiken immer noch nicht, da der Browser keine Ahnung hat, dass Domain / Mysite und Domain / Otherite vom Benutzer als "sicher" eingestuft werden. Vielleicht sollte die Frage sein, warum Sie die URL ändern möchten? Wenn es für den Benutzer verdeckt werden soll, können Sie Ihre Anwendung einfach in einem Iframe ausführen.
Robin Day
5
Sie können dies tatsächlich mit Flash tun. Sie können die URL ändern, ohne eine Anfrage zu stellen. Dies ist möglich, weil Flash außerhalb des Browsers arbeitet, aber sehr eng damit verbunden ist.
Nick Berardi
142
Ich muss sagen, dass es durchaus triftige Gründe gibt, die URL in der Adressleiste clientseitig ändern zu wollen. Wenn Sie beispielsweise eine Datentabelle mit Paging, Sortieren und Filtern haben und möchten, dass diese Dinge mit Ajax betrieben werden, die URL jedoch weiterhin so aktualisieren, dass der aktuelle Status der Seite mit einem Lesezeichen versehen werden kann. Ich kann die Sicherheitsrisiken beim Ändern des Domainnamens (Phishing usw.) verstehen, aber warum lassen Browser nicht zu, dass nur der Teil der URL rechts von der Top-Level-Domain per Skript geändert werden kann?
Sonntag Ironfoot
41
Diese Antwort ist nicht mehr 100% wahr. Siehe meine Antwort für Details.
David Murdoch
83
parent.location.hash = "hello";
Martin.
quelle
15
Ich möchte die URL ändern, nicht nur den Hash - #mydata
TheFlash
42
Das Ändern des Hashs kann in Ajax nützlich sein, da es sich um eine Art Status ohne Verwendung von Cookies handelt, mit Lesezeichen versehen und mit den Zurück-Schaltflächen des Browsers kompatibel ist. Google Mail verwendet dies heutzutage, um es browserfreundlicher zu machen.
Matthew Lock
@ Jarvis: Was ist der Unterschied?
laut
@noisy Server Side Tracking kann keine Hashes sehen, es sei denn, sie werden explizit an den Tracking-Service gesendet.
RedYetiCo
Dies ist nicht sinnvoll, wenn Sie ein MVC-Framework verwenden, das auf Hash weiterleitet, z. B. Backbone.
Catbadger
27

In modernen Browsern und HTML5 gibt es eine Methode, die pushStateim Fenster aufgerufen wird history. Dadurch wird die URL geändert und in den Verlauf verschoben, ohne dass die Seite geladen werden muss.

Sie können es so verwenden, es werden 3 Parameter benötigt, 1) Statusobjekt 2) Titel und eine URL):

window.history.pushState({page: "another"}, "another page", "example.html");

Dadurch wird die URL geändert, die Seite jedoch nicht neu geladen. Außerdem wird nicht überprüft, ob die Seite vorhanden ist. Wenn Sie also JavaScript-Code verwenden, der auf die URL reagiert, können Sie wie folgt damit arbeiten.

Es gibt history.replaceState()auch solche, die genau das Gleiche tun, außer dass der aktuelle Verlauf geändert wird, anstatt einen neuen zu erstellen!

Sie können auch eine Funktion erstellen, um zu überprüfen, ob sie history.pushStatevorhanden ist, und den Rest wie folgt fortsetzen:

function goTo(page, title, url) {
  if ("undefined" !== typeof history.pushState) {
    history.pushState({page: page}, title, url);
  } else {
    window.location.assign(url);
  }
}

goTo("another page", "example", 'example.html');

Sie können auch das #für ändern <HTML5 browsers, wodurch die Seite nicht neu geladen wird. So verwendet Angular SPA gemäß Hashtag ...

Das Ändern #ist ganz einfach und funktioniert wie folgt:

window.location.hash = "example";

Und Sie können es so erkennen:

window.onhashchange = function () {
  console.log("#changed", window.location.hash);
}
Alireza
quelle
Würde window.onhashchangeund würde window.onpopstateich in diesem Fall dasselbe tun?
J0ANMM
Wie lade ich auch Seiteninhalte? Es ersetzt nur die URL
MD. Atiqur Rahman
Laden Sie den Inhalt wie gewohnt mit Ajax.
AndroidDev
26

Der HTML5 replaceState ist die Antwort, wie bereits von Vivart und geo1701 erwähnt. Es wird jedoch nicht in allen Browsern / Versionen unterstützt. History.js schließt HTML5-Statusfunktionen ein und bietet zusätzliche Unterstützung für HTML4-Browser.

Thomas Stjernegaard Jeppesen
quelle
24

Vor HTML5 können wir verwenden:

parent.location.hash = "hello";

und:

window.location.replace("http:www.example.com");

Diese Methode lädt Ihre Seite neu, aber HTML5 hat die eingeführt, die history.pushState(page, caption, replace_url)Ihre Seite nicht neu laden sollte.

Scheinen
quelle
2
Das Problem dabei history.pushState(..)ist, dass die domänenübergreifende Richtlinie wirksam wird, wenn Sie zu einer anderen Domäne umleiten möchten. Während der window.location.replace(..)Umleitung zu einer anderen Domain ist dies möglich.
OSWorX
23

Wenn Sie Benutzern erlauben möchten, Seiten mit Lesezeichen zu versehen / zu teilen, und Sie nicht benötigen, dass es genau die richtige URL ist, und Sie für nichts anderes Hash-Anker verwenden, können Sie dies in zwei Schritten tun Teile; Sie verwenden die oben beschriebene location.hash und implementieren dann eine Überprüfung auf der Startseite, um nach einer URL mit einem Hash-Anker zu suchen und Sie zum nachfolgenden Ergebnis umzuleiten.

Zum Beispiel:

1) Benutzer ist eingeschaltet www.site.com/section/page/4

2) Der Benutzer führt eine Aktion aus, bei der die URL in www.site.com/#/section/page/6(mit dem Hash) geändert wird . Angenommen, Sie haben den richtigen Inhalt für Seite 6 in die Seite geladen, sodass der Benutzer abgesehen vom Hash nicht zu gestört ist.

3) Der Benutzer gibt diese URL an eine andere Person weiter oder setzt ein Lesezeichen

4) Jemand anderes oder derselbe Benutzer zu einem späteren Zeitpunkt geht zu www.site.com/#/section/page/6

5) Code on www.site.com/leitet den Benutzer www.site.com/section/page/6mit folgendem Befehl weiter:

if (window.location.hash.length > 0){ 
   window.location = window.location.hash.substring(1);
}

Hoffe das macht Sinn! Dies ist in einigen Situationen ein nützlicher Ansatz.

Jeremy Warne
quelle
17

Unten finden Sie die Funktion zum Ändern der URL, ohne die Seite neu zu laden. Es wird nur für HTML5 unterstützt.

  function ChangeUrl(page, url) {
        if (typeof (history.pushState) != "undefined") {
            var obj = {Page: page, Url: url};
            history.pushState(obj, obj.Page, obj.Url);
        } else {
            window.location.href = "homePage";
            // alert("Browser does not support HTML5.");
        }
    }

  ChangeUrl('Page1', 'homePage');
Suraj
quelle
2
@Green, Seite ist ein kurzer Titel für den Status, in den Sie wechseln. Firefox ignoriert diesen Parameter derzeit, obwohl er möglicherweise in Zukunft verwendet wird. Das Übergeben der leeren Zeichenfolge sollte vor zukünftigen Änderungen an der Methode sicher sein. Von: developer.mozilla.org/en-US/docs/Web/API/…
Snook
13

Alle Änderungen an der Option (entweder window.locationoder document.location) führen zu einer Anforderung für diese neue URL, wenn Sie nicht nur das URL-Fragment ändern. Wenn Sie die URL ändern, ändern Sie die URL.

Verwenden Sie serverseitige Techniken zum Umschreiben von URLs wie Apaches mod_rewrite, wenn Ihnen die aktuell verwendeten URLs nicht gefallen.

Gumbo
quelle
Kann ich "location.pathname" verwenden?
TheFlash
3
Nein, das Ändern dieses Attributs führt ebenfalls zu einer Anforderung.
Gumbo
11

Sie können Ankertags hinzufügen. Ich verwende dies auf meiner Website, damit ich mit Google Analytics verfolgen kann, welche Personen die Seite besuchen.

Ich füge einfach ein Ankertag hinzu und dann den Teil der Seite, den ich verfolgen möchte:

var trackCode = "/#" + urlencode($("myDiv").text());
window.location.href = "http://www.piano-chords.net" + trackCode;
pageTracker._trackPageview(trackCode);
Nate
quelle
9

Wie von Thomas Stjernegaard Jeppesen hervorgehoben, können Sie History.js verwenden URL-Parameter ändern, während der Benutzer durch Ihre Ajax-Links und navigiert.

Seit dieser Antwort ist fast ein Jahr vergangen, und History.js wuchs und wurde stabiler und browserübergreifender. Jetzt können damit Verlaufszustände sowohl in HTML5-kompatiblen als auch in vielen Nur-HTML4-Browsern verwaltet werden. In dieser Demo sehen Sie ein Beispiel für die Funktionsweise (sowie die Möglichkeit, seine Funktionen und Grenzen auszuprobieren.

Wenn Sie Hilfe bei der Verwendung und Implementierung dieser Bibliothek benötigen, empfehlen wir Ihnen, sich den Quellcode der Demoseite anzusehen: Sie werden sehen, dass dies sehr einfach ist.

Eine umfassende Erklärung der Probleme bei der Verwendung von Hashes (und Hashbangs) finden Sie unter diesem Link von Benjamin Lupton.

Erenor Paz
quelle
8

Verwendung history.pushState()aus der HTML 5-Verlaufs-API.

Weitere Informationen finden Sie in der HTML5-Verlaufs-API .

Prathamesh Rasam
quelle
7

Sie können diese schöne und einfache Funktion verwenden, um dies überall in Ihrer Anwendung zu tun.

function changeurl(url, title) {
    var new_url = '/' + url;
    window.history.pushState('data', 'Title', new_url);
    document.title = title;
}

Sie können nicht nur die URL bearbeiten, sondern auch den Titel aktualisieren.

Sehr hilfreich für alle.

Dheeraj Thedijje
quelle
1
Funktioniert auch für Anker wie ein Zauberwindow.history.pushState('data', 'Title', '#new_location');
BIOHAZARD