2009-07-28 20 views
105

Si javascript modifica DOM en la página A, el usuario navega a la página B y luego pulsa el botón Atrás para volver a la página A. Se pierden todas las modificaciones a DOM de la página A y se presenta al usuario versión que fue originalmente recuperada del servidor.Ajax, botón de retroceso y actualizaciones DOM

Funciona de esa manera en stackoverflow, reddit y muchos otros sitios web populares. (intente agregar un comentario de prueba a esta pregunta, luego navegue a otra página y presione el botón Atrás para volver - su comentario se "habrá ido")

Esto tiene sentido, pero algunos sitios web (apple.com, basecamphq.com etc.) están obligando de algún modo al navegador a mostrar al usuario el último estado de la página. (vaya a http://www.apple.com/ca/search/?q=ipod, haga clic en el enlace decir descargas en la parte superior y luego haga clic en el botón Atrás - todas las actualizaciones DOM se conservarán)

¿de dónde viene la inconsistencia?

+0

Curiosamente, Apple está recordando el estado sin modificar el hash .. hmmm – James

+0

Apple parece que solo está manipulando el caché de respuesta – BigBlondeViking

+0

Como otros ya han sugerido, esto no es algo relacionado con javascript o ajax. Debe eliminar esas etiquetas para obtener respuestas correctas. – BYK

Respuesta

102

Una respuesta: entre otras cosas, los eventos de descarga provocan la invalidación de la memoria caché back/forward.

Algunos navegadores almacenan el estado actual de toda la página web en el llamado "bfcache" o "caché de página". Esto les permite volver a renderizar la página muy rápidamente cuando navegan por los botones Atrás y Adelante, y conserva el estado del DOM y todas las variables de JavaScript. Sin embargo, cuando una página contiene eventos de descarga, esos eventos podrían potencialmente poner la página en un estado no funcional, por lo que la página no se almacena en bfcache y debe volver a cargarse (pero puede cargarse desde la memoria caché estándar) y volver renderizado desde cero, incluido ejecutar todos los controladores de carga. Al regresar a una página a través de bfcache, el DOM se mantiene en su estado anterior, sin necesidad de activar los controladores de carga (porque la página ya está cargada).

Tenga en cuenta que el comportamiento de bfcache es diferente del caché de navegador estándar con respecto a Cache-Control y otros encabezados HTTP. En muchos casos, los navegadores almacenarán en caché una página en bfcache, incluso si de lo contrario no la almacenaría en la memoria caché estándar.

jQuery concede automáticamente un evento de descarga a la ventana, por lo que lamentablemente usando jQuery descalificar su página se almacene en el bfcache para la preservación DOM y rápida hacia atrás/adelante. [Actualización: esto se ha solucionado en jQuery 1.4 de modo que sólo se aplica a IE]

+3

lo has clavado por completo. ambos, reddit y stackoverflow usan jquery mientras basecamp y apple usan prototypejs. esto explica mucho todo. –

+0

+1 interesante (aunque no es un navegador cruzado) la pregunta es muy diferente de cuando comenzó ... – BigBlondeViking

+1

probablemente sea un navegador cruzado porque también puedo reproducirlo en mi Internet Explorer.Estoy seguro de que cada navegador web con javascript habilitado tuvo que lidiar con este problema de todos modos. pero esto es realmente un desastre, cuando piensas en eso, el botón de retroceso siempre debería hacer que la gente vaya a la página que han visto por última vez con todas las actualizaciones de DOM, estado de javascript, etc. Los desarrolladores no deberían romper esto haciendo algo en el evento de descarga y si lo hacen, los webbrowers no deberían tratar de solucionar el problema al no usar bfcache en absoluto. todo el evento de descarga es una gran broma. Estoy seguro de que el 99% del tiempo se usa para parchar las pérdidas de memoria. –

0

Lo que está buscando es algún tipo de administración de hash de URL. El # en la url es solo para el lado del cliente.

Cuando cambia el estado de la parte posterior con JS, actualiza los datos en el # de la url.

También agrega algún tipo de sondeo que supervisa si el hash ha cambiado y carga el estado de la página en función de los datos nuevos en el hash.

Tome un vistazo a esto:

http://ajaxpatterns.org/Unique_URLs

+3

esto no tiene nada que ver con el símbolo hash. –

+3

Está equivocado, está buscando la forma más común de preservar el estado de la página en una solución AJAX. – BigBlondeViking

3

Facebook recuerda estado de la página mediante la modificación del identificador de hash en la dirección URL de peticiones Ajax. Estos cambios se registran en el historial del navegador, por lo que cuando el usuario hace clic en el botón Atrás, el hash cambia a lo que era antes. Entonces, está implícito que necesitarás un poco de Javascript para monitorear el identificador de has y reaccionar cuando el navegador lo cambie. Andreas Blixt has a hash monitoring script available.

+0

a partir de hoy no lo hace, puede decirme qué hace Facebook ahora –

2

El uso del identificador de hash/fragmento de URL es una forma bastante común de enganchar/recordar el estado en una aplicación web que se basa en las actualizaciones de Ajax y DOM. Para obtener algunas ideas, consulte el proyecto Really Simple History. Es posible controlar la URL para ver los cambios en el hash, y rsh lo hace, teniendo en cuenta las diferencias del navegador.

3

Esto no tiene nada que ver con el símbolo hash (#).

Si comprueba los encabezados HTTP de apple, simplemente almacena en caché la página.

+0

El ejemplo de Apple es pobre, no están "guardando" el estado de la página, su suposición de que el DOM se conserva mal – BigBlondeViking

+2

¿sabes qué es una actualización DOM? Eso es lo que está preguntando. –

+0

Usted no entiende. –

12

He estado tratando de conseguir Chrome se comporte como lo hace Safari, y la única forma que he encontrado que funciona es fijar Cache-control: no-store en las cabeceras. Esto obliga al navegador a recuperar la página del servidor cuando el usuario presiona el botón Atrás. No es ideal, pero es mejor que mostrar una página desactualizada.

+3

Esta es la respuesta correcta al original pregunta. Si desea forzar la recarga de un servidor en el botón Atrás, use el control de caché 'no-store, no-cache, must-revalidate'. Chrome quiere que no tienda, y IE quiere debe revalidar. Para otros navegadores (y w3c) no-cache es suficiente. – woens

1

Para cualquiera que tenga problemas con Rails y esto - su problema no es bfcache (pensé que era) - es la gema turbolinks. Here es cómo eliminarlo.

Espero que esto le ahorrará algo de tiempo y golpeando su cabeza contra la pared.

Cuestiones relacionadas