Come posso modificare l'URL senza ricaricare la pagina?


2378

Esiste un modo per modificare l'URL della pagina corrente senza ricaricare la pagina?

Vorrei accedere alla porzione prima dell'hash # se possibile.

Devo solo cambiare la parte dopo il dominio, quindi non è come se stessi violando le politiche tra domini.

 window.location.href = "www.mysite.com/page2.php";  // Sadly this reloads

139
Solo per facilitare la comprensione della domanda, questo è ciò che fa Facebook quando apri una foto, per esempio. La barra dell'URL cambia puntando DIRETTAMENTE a quella foto, così puoi condividere l'URL senza perdere la tua posizione nel sito. Ricordi i siti basati sull'inquadramento dell'ultimo decennio? Potresti ottenere solo l'URL della home page, perché stavano cambiando solo i frame interni. E quello è stato terribile.
Spidey,

Sebbene history.pushState()sia probabilmente la risposta giusta qui, in questa situazione (a seconda delle circostanze esatte ...) la possibilità di utilizzare un reindirizzamento lato server (come ad esempio tramite l'uso della direttiva RewriteRule di Apache) è qualcosa che potresti voler considerare, o almeno fare attenzione a. Ho pensato che dovesse essere menzionato!
Doin

Risposte:


2033

Questo ora può essere fatto in Chrome, Safari, Firefox 4+ e Internet Explorer 10pp4 +!

Vedi la risposta a questa domanda per ulteriori informazioni: Aggiornamento della barra degli indirizzi con nuovo URL senza hash o ricarica della pagina

Esempio:

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

È quindi possibile utilizzare window.onpopstateper rilevare la navigazione del pulsante Indietro / Avanti:

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

Per uno sguardo più approfondito sulla manipolazione della cronologia del browser, consultare questo articolo MDN .


272
Allora come fa Facebook a farlo in IE7?
Dominic

57
@CHiRiLo controlla history.js che fornisce un fallback per i browser che non supportano l'API della cronologia HTML5.
David Murdoch,

23
@infensus Se c'è un segno # nell'URL da qualche parte, quel trucco esiste da anni ..
Izkata

34
Che cosa significa la parte "pp4 +" di "IE10pp4 +"?
Scott Tesler,

34
anteprima piattaforma 4
David Murdoch,

588

HTML5 ha introdotto i metodi history.pushState()e history.replaceState(), che consentono di aggiungere e modificare le voci della cronologia, rispettivamente.

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

Maggiori informazioni su questo da qui


12
Potrebbe non funzionare file:///per motivi di sicurezza, ad es. Firefox 30. Prova localhostcon python -m SimpleHTTPServer.
Ciro Santilli 9 冠状 病 六四 事件 法轮功

6
Il primo parametro dovrebbe essere un oggetto, non solo una stringa.
Alexis Wilke,

40
IMO questa è davvero la risposta migliore. Se tutto ciò che vuoi fare è aggiornare l'URL corrente ({}, null, strNewPath) è tutto ciò che devi fare. Meglio provare prima con if (history.pushState) {}
Craig Jacobs,

7
puoi semplicemente inserire null per i primi 2 parametri se non vuoi cambiarli. Puoi anche usare un url assoluto per il terzo parametro.
Andrew

3
Sarebbe bello se mettessi qualche informazione in più proprio nella risposta. Non ho idea di cosa faccia il parametro 1.
RedClover,

130

Puoi anche utilizzare HTML5 replaceState se desideri modificare l'URL ma non vuoi aggiungere la voce alla cronologia del browser:

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

Ciò "spezzerebbe" la funzionalità del pulsante Indietro. Ciò può essere richiesto in alcuni casi, ad esempio una galleria di immagini (in cui si desidera che il pulsante Indietro torni alla pagina dell'indice della galleria invece di spostarsi indietro per ogni immagine visualizzata) fornendo a ciascuna immagine il proprio URL unico.


110

Ecco la mia soluzione (newUrl è il tuo nuovo URL che vuoi sostituire con quello attuale):

history.pushState({}, null, newUrl);

1
È meglio testare prima con if (history.pushState) {} Nel caso in cui il vecchio browser.
Craig Jacobs,

Non funzionerà più in Firefox: l'operazione non è sicura.
kkatusic,

E l'utente può anche impostare un segnalibro con quell'approccio, bellissimo! Ora posso aggiornare l'URL sull'input dell'utente e può aggiungere direttamente ai preferiti qualunque sia la sua impostazione.
codepleb

107

NOTA: se si lavora con un browser HTML5, è necessario ignorare questa risposta. Questo è ora possibile come si può vedere nelle altre risposte.

Non è possibile modificare l' URL nel browser senza ricaricare la pagina. L'URL rappresenta quale era l'ultima pagina caricata. Se lo cambi ( document.location), ricaricherà la pagina.

Una ragione ovvia è che scrivi un sito www.mysite.comche assomiglia a una pagina di accesso alla banca. Quindi si cambia la barra dell'URL del browser per dire www.mybank.com. L'utente sarà totalmente inconsapevole di ciò che sta realmente guardando www.mysite.com.


33
Non voglio cambiare il dominio, solo il percorso e il nome del file.
TheFlash

5
Ciò non impedisce ancora potenziali rischi per la sicurezza in quanto il browser non ha idea che dominio / mysite e dominio / altri siti siano entrambi considerati "sicuri" dall'utente. Forse la domanda dovrebbe essere: perché vuoi cambiare l'URL? Se è per oscurarlo dall'utente, è possibile semplicemente eseguire l'applicazione all'interno di un iframe.
Robin Day,

5
In realtà puoi farlo con Flash. Ti permetterà di modificare l'URL senza effettuare una richiesta. Questo è possibile perché Flash funziona al di fuori del browser, ma molto strettamente con esso.
Nick Berardi,

142
Devo dire che ci sono ragioni perfettamente valide per voler modificare l'URL nella barra degli indirizzi lato client. Ad esempio, se si dispone di una tabella di dati con paginazione, ordinamento e filtro e si desidera che queste cose siano alimentate da Ajax, ma si aggiorna comunque l'URL in modo che lo stato corrente della pagina sia aggiunto ai segnalibri. Riesco a comprendere i rischi per la sicurezza modificando il nome di dominio (phishing ecc.), Ma perché i browser non consentono di modificare tramite script solo la parte dell'URL a destra del dominio di livello superiore?
Domenica Ironfoot,

41
questa risposta non è più vera al 100%. Vedi la mia risposta per i dettagli.
David Murdoch,

83
parent.location.hash = "hello";

15
Voglio cambiare l'URL, non solo l'hash - #mydata
TheFlash

42
La modifica dell'hash può essere utile in Ajax in quanto è un tipo di stato senza l'uso dei cookie, è un segnalibro e compatibile con i pulsanti Indietro del browser. Gmail lo utilizza al giorno d'oggi per renderlo più adatto al browser.
Matthew Lock,

@Jarvis: qual è la differenza?
rumoroso

Il monitoraggio lato server @noisy non può vedere gli hash se non viene inviato esplicitamente al servizio di monitoraggio.
RedYetiCo

questo non è utile se stai usando un framework mvc che instrada su hash, ad esempio backbone.
catbadger,

27

Nei browser moderni e HTML5 , esiste un metodo chiamato pushStatesu finestra history. Ciò cambierà l'URL e lo sposterà nella cronologia senza caricare la pagina.

Puoi usarlo in questo modo, ci vorranno 3 parametri, 1) stato oggetto 2) titolo e un URL):

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

Questo cambierà l'URL, ma non ricaricherà la pagina. Inoltre, non controlla se la pagina esiste, quindi se esegui un codice JavaScript che reagisce all'URL, puoi lavorare con loro in questo modo.

Inoltre c'è history.replaceState()che fa esattamente la stessa cosa, tranne che modificherà la cronologia corrente invece di crearne una nuova!

Inoltre puoi creare una funzione per verificare se history.pushStateesiste, quindi proseguire con il resto in questo modo:

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');

Inoltre puoi cambiare il #for <HTML5 browsers, che non ricaricherà la pagina. Questo è il modo in cui Angular usa la SPA secondo l'hashtag ...

Cambiare #è abbastanza facile, facendo come:

window.location.hash = "example";

E puoi rilevarlo in questo modo:

window.onhashchange = function () {
  console.log("#changed", window.location.hash);
}

Sarebbe window.onhashchangee window.onpopstatefare lo stesso in questo caso?
J0ANMM,

Come caricare anche i contenuti della pagina? Sostituisce semplicemente l'URL
MD. Atiqur Rahman,

Carica i contenuti come faresti normalmente con ajax.
AndroidDev,

26

HTML5 replaceState è la risposta, come già accennato da Vivart e geo1701. Tuttavia, non è supportato in tutti i browser / versioni. History.js racchiude le funzionalità di stato HTML5 e fornisce supporto aggiuntivo per i browser HTML4.


24

Prima di HTML5 possiamo usare:

parent.location.hash = "hello";

e:

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

Questo metodo ricaricherà la tua pagina, ma HTML5 ha introdotto il history.pushState(page, caption, replace_url)che non dovrebbe ricaricare la tua pagina.


2
Il problema history.pushState(..)è che, se si desidera reindirizzare a un altro dominio, entra in vigore la politica interdominio. Mentre con il window.location.replace(..)reindirizzamento a un altro dominio è possibile.
OSWorX,

23

Se quello che stai cercando di fare è consentire agli utenti di aggiungere segnalibri / condividere pagine e non hai bisogno che sia esattamente l'URL giusto e non stai usando gli ancoraggi hash per qualcos'altro, allora puoi farlo in due parti; si utilizza location.hash discusso in precedenza, quindi si implementa un controllo nella home page, per cercare un URL con un ancoraggio hash al suo interno e reindirizzare l'utente al risultato successivo.

Per esempio:

1) L'utente è attivo www.site.com/section/page/4

2) L'utente esegue alcune azioni che modificano l'URL in www.site.com/#/section/page/6(con l'hash). Supponi di aver caricato il contenuto corretto per pagina 6 nella pagina, quindi a parte l'hash l'utente non è troppo disturbato.

3) L'utente passa questo URL a qualcun altro o lo aggiunge ai segnalibri

4) Qualcun altro, o lo stesso utente in un secondo momento, va a www.site.com/#/section/page/6

5) Codice su www.site.com/reindirizza l'utente a www.site.com/section/page/6, usando qualcosa del genere:

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

Spero che abbia un senso! È un approccio utile per alcune situazioni.


17

Di seguito è la funzione per modificare l'URL senza ricaricare la pagina. È supportato solo per HTML5.

  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');

2
@Verde, pagina è un titolo breve per lo stato in cui ti stai spostando. Firefox attualmente ignora questo parametro, sebbene possa utilizzarlo in futuro. Passare la stringa vuota qui dovrebbe essere sicuro contro future modifiche al metodo. Da: developer.mozilla.org/en-US/docs/Web/API/…
Snook

13

Qualsiasi modifica della posizione (o window.locationo document.location) provocherà una richiesta su quel nuovo URL, se non stai semplicemente cambiando il frammento di URL. Se si modifica l'URL, si modifica l'URL.

Utilizza tecniche di riscrittura degli URL lato server come mod_rewrite di Apache se non ti piacciono gli URL che stai attualmente utilizzando.


Posso usare "location.pathname" ??
TheFlash

3
No, la modifica di tale attributo causerà anche una richiesta.
Gumbo,

11

È possibile aggiungere tag di ancoraggio. Lo uso sul mio sito in modo da poter monitorare con Google Analytics ciò che le persone visitano sulla pagina.

Aggiungo solo un tag di ancoraggio e quindi la parte della pagina che voglio monitorare:

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

9

Come sottolineato da Thomas Stjernegaard Jeppesen, è possibile utilizzare History.js per modificare i parametri URL mentre l'utente naviga attraverso i collegamenti e le app Ajax.

È passato quasi un anno da quella risposta, e History.js è cresciuto, è diventato più stabile e cross-browser. Ora può essere utilizzato per gestire gli stati della cronologia in conformità a HTML5 e in molti browser solo HTML4. In questa demo puoi vedere un esempio di come funziona (oltre a poterne provare funzionalità e limiti.

Se hai bisogno di aiuto su come utilizzare e implementare questa libreria, ti suggerisco di dare un'occhiata al codice sorgente della pagina demo: vedrai che è molto facile da fare.

Infine, per una spiegazione esauriente di quali possano essere i problemi relativi all'uso degli hash (e degli hashbang), dai un'occhiata a questo link di Benjamin Lupton.



7

È possibile utilizzare questa bella e semplice funzione per farlo ovunque nella propria applicazione.

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

Non solo puoi modificare l'URL ma puoi aggiornare il titolo insieme ad esso.

Abbastanza utile a tutti.


1
Funziona come un fascino anche per le ancorewindow.history.pushState('data', 'Title', '#new_location');
BIOHAZARD
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.