¿Cómo forzar la recarga de una página cuando se usa el botón de retroceso del navegador?


84

Necesito detectar de alguna manera que el usuario ha presionado un botón de retroceso del navegador y volver a cargar la página con actualización (recargando el contenido y CSS) usando jquery.

¿Cómo detectar dicha acción a través de jquery?

Porque ahora mismo algunos elementos no se vuelven a cargar si uso el botón Atrás en un navegador. Pero si utilizo enlaces en el sitio web, todo se actualiza y se muestra correctamente.

¡IMPORTANTE!

Algunas personas probablemente han entendido mal lo que quiero. No quiero actualizar la página actual. Quiero actualizar la página que se carga después de presionar el botón Atrás. esto es lo que quiero decir de una manera más detallada:

  1. el usuario está visitando la página 1.
  2. mientras está en la página 1: hace clic en un enlace a la página 2.
  3. se le redirige a la página2
  4. ahora (¡parte importante!) hace clic en el botón Atrás en el navegador porque quiere volver a la página1
  5. él está de vuelta en la página 1 - y ahora la página 1 se está recargando y se alerta algo como "¡Has vuelto!"

En lugar de piratear el comportamiento normal del usuario, ¿por qué no intenta comprender por qué su código no funciona al cargar la página y necesita que la página se vuelva a cargar?
Lelio Faieta

2
@LelioFaieta Cambio de clases para mostrar cambios. Si el usuario hace clic en algo, el valor cambia en la base de datos a través de ajax. Cuando el ajax finaliza, la clase css cambia, por ejemplo, de ona off. Y está bien, está guardado en db, los usuarios ven todo correctamente. Ahora hace clic en otro enlace. Por ejemplo, la página sobre nosotros, ¿verdad? Ahora, está en la página sobre nosotros. Be decide volver a la página anterior y hace clic en el botón Atrás en el navegador. Y cuando está de regreso, ve los cambios en la página cuando el navegador mostró la página (probablemente algo de caché del navegador) antes de activar el ajax (clases de encendido / apagado)
John Doeherskij

1
¿Está utilizando get o post para su llamada Ajax?
Lelio Faieta

1
@LelioFaieta part2 .. También utilizo el atributo de datos y no tiene ningún efecto. Todo sería genial si se volviera a cargar la página. Si presiono F5 en esa página, se muestran los valores que cambió a través de ajax. Creo que este es un problema relacionado con el chaching del navegador, cuando la parte css / html no está completamente recargada. Se recarga solo después de presionar f5
John Doeherskij

@LelioFaieta $.ajax({ url: url, method: 'post', processData: false, contentType: false, cache: false, dataType: 'json', data: formData, })¿Crees que esto podría ser por ajax? Sería genial si este fuera el caso.
John Doeherskij

Respuestas:


86

Puede usar el pageshowevento para manejar la situación cuando el navegador navega a su página a través del recorrido del historial:

window.addEventListener( "pageshow", function ( event ) {
  var historyTraversal = event.persisted || 
                         ( typeof window.performance != "undefined" && 
                              window.performance.navigation.type === 2 );
  if ( historyTraversal ) {
    // Handle page restore.
    window.location.reload();
  }
});

Tenga en cuenta que la caché HTTP también puede estar involucrada. Debe configurar los encabezados HTTP relacionados con la caché adecuados en el servidor para almacenar en caché solo aquellos recursos que deben almacenarse en caché. También se puede hacer recarga forzada al navegador instuct ignorar HTTP caché: window.location.reload( true ). Pero no creo que sea la mejor solución.

Para más información consultar:


¿Podrías ayudar al usuario Dhiraj? Está en el camino correcto pero se está recargando dos veces. Por cierto, lo intenté window.addEventListener( "unload", function() {} );pero no hace nada, el botón de retroceso funciona como antes, sin ningún cambio; (
John Doeherskij

¿Cómo descargar BFCache? ¿Podrías actualizar tu código con información más específica? Esta línea window.addEventListener( "unload", function() {} );no funciona. Esta completo?
John Doeherskij

El recorrido del historial de Chrome es algo confuso. Pruebe la pageshowsolución.
Leonid Vasilev

1
Todavía veo una carga doble; (Una vez que el Firefox predeterminado (muestra la página anterior; ¿de la caché del navegador tal vez?) Y luego el script se activa nuevamente. El script lo recargará en la etapa actual, pero todavía veo el estado anterior por un segundo más o menos; (tengo el código adentro$(document).ready( function() { /* code here */ });
John Doeherskij

3
window.performance.navigationes obsoleto. Para verificar el tipo de navegación que utilicéwindow.performance.getEntriesByType("navigation")[0].type === "back_forward"
zero01alpha

49

Ha pasado un tiempo desde que se publicó esto, pero encontré una solución más elegante si no necesita admitir navegadores antiguos.

Puedes hacer un chequeo con

performance.navigation.type

La documentación, incluida la compatibilidad con el navegador, está aquí: https://developer.mozilla.org/en-US/docs/Web/API/Performance/navigation

Entonces, para ver si la página se cargó desde el historial usando back, puede hacer

if(performance.navigation.type == 2){
   location.reload(true);
}

El 2indica que se accedió a la página navegando en el historial. Otras posibilidades son-

0:Se accedió a la página siguiendo un enlace, un marcador, un envío de formulario o un guión, o escribiendo la URL en la barra de direcciones.

1:Se accedió a la página haciendo clic en el botón Recargar o mediante el método Location.reload ().

255: Cualquier otra forma

Estos se detallan aquí: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigation


Nota Performance.navigation.type ahora está en desuso en favor de PerformanceNavigationTiming.type que devuelve 'navigate' / 'reload' / 'back_forward' / 'prerender': https://developer.mozilla.org/en-US/docs/Web / API / PerformanceNavigationTiming / type


2
Este cheque funcionó para mí. ¿Qué significa exactamente el 2?
RitchieD

Esto funcionó a las mil maravillas ... Lo coloqué en la parte superior de la mayor parte del área ... y la página se estaba recargando sin cargar ningún otro script.
NMathur

Esto funcionó a las mil maravillas. Gran hallazgo ... Es muy rápido y confiable, no como otras respuestas que fueron lentas en comparación con esta. TY
WEBBer

este funcionó con el navegador Chrome y no con
Firefox

7
Esto está desaprobado (consulte w3c.github.io/navigation-timing/#obsolete ).
David Vielhuber

22

Solo usa jquery:

jQuery( document ).ready(function( $ ) {

   //Use this inside your document ready jQuery 
   $(window).on('popstate', function() {
      location.reload(true);
   });

});

Lo anterior funcionará al 100% cuando también se haya hecho clic en el botón Atrás o Adelante usando ajax.

si no es así, debe haber una configuración incorrecta en una parte diferente del script.

Por ejemplo, es posible que no se recargue si se usa algo como uno de los ejemplos de la publicación anterior window.history.pushState('', null, './');

así que cuando lo use history.pushState(); asegúrese de usarlo correctamente.

Sugerencia en la mayoría de los casos solo necesitará:

history.pushState(url, '', url); 

No window.history ... y asegúrese de que la URL esté definida.

Espero que ayude..



@RitchieD - A partir de hoy, esto funciona bien en IE11 en Windows 10. Nota: No estoy usando EDGE.
Dan G

No soy fanático de las respuestas "solo usa jQuery", lo siento
Steven

Quitaría "true" de la recarga para usar la caché HTTP. No tiene sentido recargar los activos en la mayoría de los casos.
Konyak

14

Dado performance.navigationque ahora está en desuso, puede probar esto:

var perfEntries = performance.getEntriesByType("navigation");

if (perfEntries[0].type === "back_forward") {
    location.reload(true);
}

Esta es la respuesta más actualizada
Java_Man

Este código debe combinarse con el código en la respuesta de Leonid anterior.
gornvix

Esto está funcionando bien para mí. Probé en los últimos Chrome, Firefox, IE y Edge. No comprobé Safari en Mac.
Tasawar Hussain

6

Debe utilizar una entrada oculta como indicador de actualización, con un valor de "no":

<input type="hidden" id="refresh" value="no">

Ahora, usando jQuery, puede verificar su valor:

$(document).ready(function(e) {
    var $input = $('#refresh');

    $input.val() == 'yes' ? location.reload(true) : $input.val('yes');
});

Cuando hace clic en el botón Atrás, los valores en los campos ocultos conservan el mismo valor que cuando salió originalmente de la página.

Entonces, la primera vez que cargue la página, el valor de la entrada será "no". Cuando regrese a la página, será "sí" y su código JavaScript activará una actualización.


1
No funciona. He probado Firefox y Chrome y no funciona.
John Doeherskij

Por favor, revise mi pregunta actualizada, tal vez usted y otros me entendieron mal. Ahora es mucho más claro lo que quiero lograr. Gracias.
John Doeherskij

Sí, lo entendí mal, gracias por actualizar la pregunta en detalle.
Dhiraj

ahora funciona. Sin embargo, se está recargando 2 veces y parece un poco extraño. Primera vez que se recarga. nada: este es probablemente el comportamiento predeterminado del navegador. La segunda vez que se recarga, a través de su secuencia de comandos, los valores se actualizan como debería ser, pero se ve mal porque se recarga dos veces. ¿Alguna idea de cómo mejorarlo un poco, para que la recarga se vea mejor o se recargue solo una vez? Se ve mejor en Chrome que en Firefox, la recarga es más rápida, pero todavía veo el estado anterior original (por un segundo o medio segundo) y la recarga del script es solo después de eso.
John Doeherskij

¿Alguna idea nueva de cómo solucionar la "doble carga"?
John Doeherskij

6

Una alternativa que me solucionó el problema es desactivar la caché de la página. Eso hace que el navegador obtenga la página del servidor en lugar de usar una versión en caché:

Response.AppendHeader("Cache-Control","no-cache, no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "0");

La mejor solución, pero aquí está la versión que utilicé. Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetMaxAge(TimeSpan.Zero); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); Response.Cache.SetNoStore();
celo

2

Actualmente, esta es la página de recarga de forma más actualizada si el usuario hace clic en el botón Atrás.

const [entry] = performance.getEntriesByType("navigation");

// Show it in a nice table in the developer console
console.table(entry.toJSON());

if (entry["type"] === "back_forward")
    location.reload();

Vea aquí la fuente


1

Recargar es fácil. Deberías usar:

location.reload(true);

Y detectar de nuevo es:

window.history.pushState('', null, './');
  $(window).on('popstate', function() {
   location.reload(true);
});

No funciona; (Lo he intentado en alert('test');lugar de location.reload(true);pero todavía nada. He intentado firefox y chrome pero nada. Lo he intentado dentro del documento listo, fuera, pero nada funciona. Si intento una alerta simple () o cualquier código jquery que funcione. tengo mucho código jquery en mi página y funciona.
John Doeherskij

He editado la respuesta, prueba una nueva solución. La cosa es que debe presionar el estado antes, o no obtendrá el evento popstate.
Anton Stepanenkov

Probablemente hayas entendido mal lo que yo quiero. He actualizado mi pregunta con una descripción más detallada. Por favor, compruébalo de nuevo si tienes tiempo, gracias.
John Doeherskij

0

Use la siguiente metaetiqueta en su archivo de encabezado html, esto funciona para mí.

<meta http-equiv="Pragma" content="no-cache">

Esto no vuelve a cargar la página cuando está de vuelta, que OP solicitó
Timberman

-1

Encontré la mejor respuesta y me está funcionando perfectamente

solo usa este sencillo script en tu enlace

<A HREF="javascript:history.go(0)">next page</A>

o el evento de clic de botón

<INPUT TYPE="button" onClick="history.go(0)" VALUE="next page">

cuando usa esto, primero actualiza su página y luego va a la página siguiente, cuando regrese, tendrá el último estado actualizado.

Lo he usado en un inicio de sesión CAS y me da lo que quiero. Espero eso ayude .......

detalles encontrados desde aquí


Esto no me funciona. ¿Qué representa el "0"?
Vincent
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.