web-dev-qa-db-fra.com

Ajax, bouton retour et mises à jour DOM

Si javascript modifie le DOM dans la page A, l'utilisateur accède à la page B, puis clique sur le bouton de retour pour revenir à la page A. Toutes les modifications apportées au DOM de la page A sont perdues et l'utilisateur se voit présenter la version qui a été récupérée à l'origine sur le serveur.

Cela fonctionne de cette façon sur stackoverflow, reddit et de nombreux autres sites Web populaires. (essayez d'ajouter un commentaire de test à cette question, puis accédez à une autre page et appuyez sur le bouton de retour pour revenir - votre commentaire sera "disparu")

Cela a du sens, mais certains sites Web (Apple.com, basecamphq.com, etc.) obligent en quelque sorte le navigateur à informer l'utilisateur du dernier état de la page. (allez à http://www.Apple.com/ca/search/?q=iPod , cliquez sur le lien dire Téléchargements en haut puis cliquez sur le bouton de retour - toutes les mises à jour DOM seront conservées)

d'où vient l'incohérence?

112
lubos hasko

Une réponse: Entre autres choses, les événements de déchargement provoquent l'invalidation du cache arrière/avant .

Certains navigateurs stockent l'état actuel de la page Web entière dans le soi-disant "bfcache" ou "cache de page". Cela leur permet de restituer la page très rapidement lors de la navigation via les boutons Précédent et Suivant, et préserve l'état du DOM et de toutes les variables JavaScript. Cependant, lorsqu'une page contient des événements de déchargement, ces événements peuvent potentiellement mettre la page dans un état non fonctionnel, et donc la page n'est pas stockée dans le bfcache et doit être rechargée (mais peut être chargée à partir du cache standard) et rendu à partir de zéro, y compris l'exécution de tous les gestionnaires de charge. Lors du retour à une page via bfcache, le DOM est conservé dans son état précédent, sans avoir besoin de déclencher des gestionnaires de chargement (car la page est déjà chargée).

Notez que le comportement de bfcache est différent du cache de navigateur standard en ce qui concerne Cache-Control et d'autres en-têtes HTTP. Dans de nombreux cas, les navigateurs mettent en cache une page dans le bfcache même s'il ne la stockerait pas autrement dans le cache standard.

jQuery attache automatiquement un événement de déchargement à la fenêtre, donc malheureusement l'utilisation de jQuery disqualifiera votre page d'être stockée dans le bfcache pour la préservation du DOM et un retour/avance rapide. [Mise à jour: cela a été corrigé dans jQuery 1.4 afin qu'il ne s'applique qu'à IE]

105
Miles

J'ai essayé de faire en sorte que Chrome se comporte comme Safari, et le seul moyen que j'ai trouvé qui fonctionne est de définir Cache-control: no-store dans les en-têtes. Cela oblige le navigateur à récupérer la page à partir du serveur lorsque l'utilisateur appuie sur le bouton de retour. Pas idéal, mais mieux que d'afficher une page obsolète.

14
nornagon

Cela n'a rien à voir avec le symbole de hachage (#).

Si vous souhaitez vérifier les en-têtes HTTP d'Apple, il s'agit simplement de mettre la page en cache.

3
Luca Matteis

Facebook se souvient de l'état de la page en modifiant l'identifiant de hachage dans l'URL pour les demandes ajax. Ces modifications sont enregistrées dans l'historique du navigateur, donc lorsque l'utilisateur clique sur le bouton de retour, le hachage change comme avant. Il est donc implicite que vous aurez besoin de Javascript pour surveiller l'identifiant has et réagir lorsqu'il est modifié par le navigateur. Andreas Blixt a un script de surveillance de hachage disponible .

3
Josh Stodola

L'utilisation de l'URL de hachage/identificateur de fragment est une méthode assez courante pour accrocher/mémoriser l'état dans une application Web qui repose sur les mises à jour Ajax et DOM.

Consultez le projet Histoire vraiment simple pour quelques idées. Il est possible de surveiller l'URL pour les modifications du hachage, et rsh le fait, en tenant compte des différences de navigateur.

2
Peter

Pour tous ceux qui ont des problèmes avec Rails et ceci - votre problème n'est pas bfcache (je pensais que c'était le cas) - c'est le joyau turbolinks. Ici est de savoir comment le supprimer.

J'espère que cela vous fera gagner du temps et vous cogner la tête contre le mur.

1
Yuval Karmi

Ce que vous recherchez est un type de gestion de hachage d'URL. Le # dans l'url est réservé au client uniquement.

Lorsque vous modifiez l'état de l'arrière avec JS, vous mettez à jour les données dans le # de l'URL.

Vous ajoutez également un type d'interrogation qui surveille si le hachage a changé et charge l'état de la page en fonction des nouvelles données du hachage.

Regarde ça:

http://ajaxpatterns.org/Unique_URLs

0
BigBlondeViking