¿Cómo modifico la URL sin volver a cargar la página?

2680

¿Hay alguna forma de que pueda modificar la URL de la página actual sin volver a cargar la página?

Me gustaría acceder a la parte antes del hash # si es posible.

Solo necesito cambiar la parte después del dominio, por lo que no es como si estuviera violando las políticas de dominios cruzados.

 window.location.href = "www.mysite.com/page2.php";  // Sadly this reloads
2
  • 162
    Solo para facilitar la comprensión de la pregunta, esto es lo que hace Facebook cuando abres una foto, por ejemplo. La barra de URL cambia para apuntar DIRECTAMENTE a esa foto, por lo que puede compartir la URL sin perder el lugar del sitio en el que se encuentra. ¿Recuerda los sitios basados ​​en marcos de la última década? Solo podía obtener la URL de la página de inicio, porque solo cambiaban los marcos internos. Y eso fue terrible.
    Spidey
    19/04/12 a las 17:59
  • 5
    Si bien history.pushState()es probablemente la respuesta correcta aquí, en esta situación (dependiendo de las circunstancias exactas ...) la posibilidad de usar una redirección del lado del servidor (como mediante el uso de la directiva RewriteRule de Apache) es algo que quizás desee considerar, o al menos ser consciente de. ¡Solo pensé que debería ser mencionado!
    Doin
    14/03/20 a las 6:37
2243

¡Esto ahora se puede hacer en Chrome, Safari, Firefox 4+ e Internet Explorer 10pp4 +!

Consulte la respuesta de esta pregunta para obtener más información: Actualizar la barra de direcciones con una nueva URL sin hash o volver a cargar la página

Ejemplo:

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

A continuación, puede utilizar window.onpopstatepara detectar la navegación del botón de retroceso / avance:

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

Para obtener una visión más detallada de la manipulación del historial del navegador, consulte este artículo de MDN .

3
  • 1
    Tenga en cuenta que el OP deja en claro que no están intentando navegar a un origen diferente ; "no es como si estuviera violando políticas de dominios cruzados". - sin embargo, estoy tratando de hacer eso, y la window.historyAPI no permite la navegación de origen cruzado a través de pushState, (lo cual es razonable ... como dice el sitio de Mozilla, "La nueva URL debe tener el mismo origen que la URL actual ; de lo contrario, pushState () lanzará una excepción. ") 17 de marzo a las 19:29
  • 1
    ¿Puedo preguntar cuál es el valor de response.html? ¿Es una cadena de HTML? 19 de mayo a las 5:42
  • 1
    ¿Qué datos se deben pasar a "respuesta"? 4 de junio a las 21:32
709

HTML5 introdujo los métodos history.pushState()y history.replaceState(), que le permiten agregar y modificar entradas del historial, respectivamente.

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

Lea más sobre esto desde aquí.

2
167

También puede usar HTML5 replaceState si desea cambiar la URL pero no desea agregar la entrada al historial del navegador:

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

Esto 'rompería' la funcionalidad del botón de retroceso. Esto puede ser necesario en algunos casos, como una galería de imágenes (donde desea que el botón Atrás regrese a la página de índice de la galería en lugar de retroceder a través de todas y cada una de las imágenes que vio) mientras le da a cada imagen su propia URL única.

0
156

Aquí está mi solución (newUrl es su nueva URL que desea reemplazar con la actual):

history.pushState({}, null, newUrl);
5
  • 6
    Es mejor probar primero con if (history.pushState) {} Por si acaso el navegador antiguo. 29 de agosto de 2016 a las 0:14
  • 1
    Esto ya no funciona, obtendrá en Firefox: La operación es insegura. 9/11/2017 a las 10:19
  • Y el usuario puede incluso establecer un marcador con ese enfoque, ¡hermoso! Ahora puedo actualizar la URL en la entrada del usuario y él puede marcar directamente sus configuraciones. 3 de junio de 2020 a las 7:26
  • 1
    Hey kkatusic, por eso Craig Jacobs dijo TEST. Lo prueba intentando ejecutar la nueva versión html5 (prueba 1) y si eso falla, prueba la versión anterior y si falla, tiene problemas, si la prueba tiene éxito para cualquiera de los objetos, entonces sabrá si el navegador es nuevo o antiguo. compañero de lógica bastante simple! ¡Vota a favor de Craig! :) 6/10/20 a las 8:44
  • @GregoryBowers No creo que kkatusic esté diciendo que el método no existe, dijo que muestra un error / advertencia de seguridad cuando se ejecuta. Entonces esa prueba no fallaría y aún ejecutaría la función. La prueba sugerida por Craig no "intenta ejecutar la nueva función html5", solo verifica que exista en el objeto de historial. 28 de mayo a las 4:39
116

NOTA: Si está trabajando con un navegador HTML5, debe ignorar esta respuesta. Esto ahora es posible, como se puede ver en las otras respuestas.

No hay forma de modificar la URL en el navegador sin volver a cargar la página. La URL representa cuál fue la última página cargada. Si lo cambia ( document.location), volverá a cargar la página.

Una razón obvia es que escribe un sitio www.mysite.comque parece una página de inicio de sesión bancaria. Luego cambia la barra de URL del navegador para decir www.mybank.com. El usuario no se dará cuenta por completo de lo que realmente está mirando www.mysite.com.

1
  • elimínelo o agregue html4, porque actualmente se muestra en la búsqueda de Google como respuesta rápida
    Eugene
    19 jul a las 16:18
90
parent.location.hash = "hello";
7
  • 17
    Quiero cambiar la URL, no solo el hash - #mydata 14 de mayo de 2009 a las 18:26
  • 42
    Cambiar el hash puede ser útil en ajax, ya que es un tipo de estado sin el uso de cookies, se puede marcar como favorito y es compatible con los botones de retroceso del navegador. Gmail usa esto hoy en día para hacerlo más amigable con el navegador. 24 de nov. De 2009 a las 8:32
  • @Jarvis: ¿cuál es la diferencia?
    noisy
    17 de julio de 2013 a las 7:07
  • @noisy El seguimiento del lado del servidor no puede ver hash a menos que se envíe al servicio de seguimiento explícitamente.
    MLK.DEV
    6/11/2014 a las 22:07
  • esto no es útil si está utilizando un marco mvc que se enruta en hash, por ejemplo, backbone. 1 de feb. De 2017 a las 13:57
41

En los navegadores modernos y HTML5 , hay un método llamado pushStateen window history. Eso cambiará la URL y la enviará al historial sin cargar la página.

Puede usarlo así, tomará 3 parámetros, 1) objeto de estado 2) título y una URL):

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

Esto cambiará la URL, pero no volverá a cargar la página. Además, no verifica si la página existe, por lo que si usa algún código JavaScript que reaccione a la URL, puede trabajar con ellos de esta manera.

Además, hay una history.replaceState()que hace exactamente lo mismo, ¡excepto que modificará el historial actual en lugar de crear uno nuevo!

También puede crear una función para verificar si history.pushStateexiste, luego continuar con el resto de esta manera:

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

Además, puede cambiar el #para <HTML5 browsers, lo que no volverá a cargar la página. Esa es la forma en que Angular usa para hacer SPA según el hashtag ...

Cambiar #es bastante fácil, haciendo lo siguiente:

window.location.hash = "example";

Y puedes detectarlo así:

window.onhashchange = function () {
  console.log("#changed", window.location.hash);
}
3
  • ¿Haría window.onhashchangey window.onpopstateharía lo mismo en este caso?
    J0ANMM
    17/07/18 a las 11:54
  • ¿Cómo cargar el contenido de la página también? Simplemente reemplaza la URL 14/09/18 a las 13:54
  • Cargue contenido como lo haría normalmente con ajax. 15/09/18 a las 16:27
27

El HTML5 replaceState es la respuesta, como ya lo mencionaron Vivart y geo1701. Sin embargo, no es compatible con todos los navegadores / versiones. History.js incluye las características de estado de HTML5 y proporciona soporte adicional para los navegadores HTML4.

26

Antes de HTML5 podemos usar:

parent.location.hash = "hello";

y:

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

Este método recargará su página, pero HTML5 introdujo el history.pushState(page, caption, replace_url)que no debería recargar su página.

1
  • 2
    El problema history.pushState(..)es que si desea redirigir a otro dominio, la política de dominio cruzado entra en vigencia. Mientras que con la window.location.replace(..)redirección a otro dominio es posible.
    OSWorX
    12 de mayo de 2018 a las 21 h.
24

Si lo que está tratando de hacer es permitir que los usuarios marquen / compartan páginas, y no necesita que sea exactamente la URL correcta, y no está usando anclajes hash para nada más, entonces puede hacerlo en dos partes; usas la ubicación. hash discutido anteriormente, y luego implemente una verificación en la página de inicio, para buscar una URL con un ancla de hash en ella, y lo redireccione al resultado posterior.

Por ejemplo:

  1. El usuario está activado www.site.com/section/page/4

  2. El usuario realiza una acción que cambia la URL a www.site.com/#/section/page/6(con el hash). Supongamos que ha cargado el contenido correcto para la página 6 en la página, por lo que, aparte del hash, el usuario no se molesta demasiado.

  3. El usuario pasa esta URL a otra persona o la agrega a marcadores.

  4. Alguien más, o el mismo usuario en una fecha posterior, va a www.site.com/#/section/page/6

  5. El código en www.site.com/redirige al usuario a www.site.com/section/page/6, usando algo como esto:

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

¡Espero que tenga sentido! Es un enfoque útil para algunas situaciones.

17

A continuación se muestra la función para cambiar la URL sin volver a cargar la página. Solo es compatible con 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');
1
  • 2
    @Green, la página es un título corto para el estado al que se está mudando. Actualmente, Firefox ignora este parámetro, aunque puede usarlo en el futuro. Pasar la cadena vacía aquí debería ser seguro contra futuros cambios en el método. De: developer.mozilla.org/en-US/docs/Web/API/…
    Snook
    27 de mayo de 2016 a las 7:41
14

Puede utilizar esta hermosa y sencilla función para hacerlo en cualquier lugar de su aplicación.

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

No solo puede editar la URL, sino que también puede actualizar el título.

2
  • 1
    Funciona como un encanto incluso para anclas. window.history.pushState('data', 'Title', '#new_location'); 7 feb.20 a las 11:36
  • 1
    ¿Por qué no usas el argumento 'título' como título en pushState?
    Xerus
    8 de febrero a las 19:40
13

Cualquier cambio de la ubicación ( window.locationo bien document.location) provocará una solicitud en esa nueva URL, si no solo está cambiando el fragmento de la URL. Si cambia la URL, cambia la URL.

Utilice técnicas de reescritura de URL del lado del servidor como mod_rewrite de Apache si no le gustan las URL que está utilizando actualmente.

2
  • ¿Puedo usar "location.pathname"? 5 de mayo de 2009 a las 11:09
  • 3
    No, cambiar ese atributo también provocará una solicitud.
    Gumbo
    5 de mayo de 2009 a las 11:47 am
11

Puede agregar etiquetas de anclaje. Utilizo esto en mi sitio para poder rastrear con Google Analytics lo que la gente está visitando en la página.

Solo agrego una etiqueta de anclaje y luego la parte de la página que quiero rastrear:

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

Como señaló Thomas Stjernegaard Jeppesen, puede usar History.js para modificar los parámetros de URL mientras el usuario navega a través de sus enlaces y aplicaciones de Ajax.

Ha pasado casi un año desde esa respuesta, y History.js creció y se volvió más estable y entre navegadores. Ahora se puede utilizar para administrar estados de historial en navegadores compatibles con HTML5, así como en muchos navegadores solo HTML4. En esta demo puedes ver un ejemplo de cómo funciona (además de poder probar sus funcionalidades y límites.

Si necesita ayuda sobre cómo usar e implementar esta biblioteca, le sugiero que eche un vistazo al código fuente de la página de demostración: verá que es muy fácil de hacer.

Finalmente, para obtener una explicación completa de cuáles pueden ser los problemas relacionados con el uso de hashes (y hashbangs), consulte este enlace de Benjamin Lupton.

8

Utilícelo history.pushState()desde la API de historial de HTML 5.

Consulte la API de historial de HTML5 para obtener más detalles.

7

Tu nueva URL.

let newUrlIS =  window.location.origin + '/user/profile/management';

En cierto sentido, llamar a pushState () es similar a configurar window.location = "#foo", en el sentido de que ambos también crearán y activarán otra entrada de historial asociada con el documento actual. Pero pushState () tiene algunas ventajas:

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

Puede consultar la raíz: https://developer.mozilla.org/en-US/docs/Web/API/History_API

1
  • por favor agregue una referencia a las supuestas "ventajas" de pushState :)
    Xerus
    8 de febrero a las 19:40
1

Este código me funciona. Lo usé en mi aplicación en ajax.

history.pushState({ foo: 'bar' }, '', '/bank');

Una vez que una página se carga en una ID usando ajax, cambia la URL del navegador automáticamente sin volver a cargar la página.

Esta es la función ajax a continuación.

function showData(){
    $.ajax({
      type: "POST",
      url: "Bank.php", 
      data: {}, 
      success: function(html){          
        $("#viewpage").html(html).show();
        $("#viewpage").css("margin-left","0px");
      }
    });
  }

Ejemplo: Desde cualquier página o controlador como "Panel de control", cuando hago clic en el banco, carga la lista de bancos usando el código ajax sin recargar la página. En este momento, no se cambiará la URL del navegador.

history.pushState({ foo: 'bar' }, '', '/bank');

Pero cuando uso este código en ajax, cambia la URL del navegador sin volver a cargar la página. Este es el código ajax completo aquí a continuación.

function showData(){
        $.ajax({
          type: "POST",
          url: "Bank.php", 
          data: {}, 
          success: function(html){          
            $("#viewpage").html(html).show();
            $("#viewpage").css("margin-left","0px");
            history.pushState({ foo: 'bar' }, '', '/bank');
          }
        });
      }
0

Esto es todo lo que necesitará para navegar sin recargar.

// add setting without reload 
location.hash = "setting";

// if url change with hash do somthing
window.addEventListener('hashchange', () => {
    console.log('url hash changed!');
});

// if url change do somthing (dont detect changes with hash)
//window.addEventListener('locationchange', function(){
//    console.log('url changed!');
//})


// remove #setting without reload 

history.back();
0

Simplemente use, no recargará la página, sino solo la URL:

$('#form_name').attr('action', '/shop/index.htm').submit();
1
  • Esto no tiene sentido 27 de agosto a las 7:08