47 votes

Le problème du bouton retour de Safari

Je fais quelques petits travaux de programmation et de web pour un collège communautaire local. Ce travail comprend la maintenance d'un site web très volumineux et destructeur d'âme qui consiste en un fatras de VBScript, de javascript, d'éléments générés par Dreamweaver et d'une collection de modules complémentaires que divers escrocs les ont convaincus d'acheter au fil des ans.

Il y a quelques jours, j'ai reçu un appel m'indiquant que le site Web se bloquait pour les utilisateurs de Safari. Ok, premièrement, je télécharge Safari (v3.1.2), deuxièmement, je navigue sur le site. Tout semble fonctionner correctement.

Pour faire court, j'ai finalement isolé le problème et il est lié au bouton retour de Safari. Le site Web utilise un menu javascript sophistiqué qui fonctionne dans tous les navigateurs que j'ai essayés, y compris Safari, la première fois. Mais dans Safari, si vous suivez un lien hors de la page et que vous appuyez ensuite sur le bouton retour, le menu ne fonctionne plus.

J'ai créé une page web simplifiée pour illustrer le principe.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body onload="alert('Hello');">
<a href="http://www.codinghorror.com">Coding Horror</a>
</body>
</html>

Chargez la page et vous verrez la boîte d'alerte. Suivez ensuite le lien hors de la page et appuyez sur le bouton Retour. Dans IE et Firefox, la boîte d'alerte s'affiche à nouveau, mais pas dans Safari.

Après une recherche vigoureuse sur Google, j'ai découvert d'autres personnes ayant des problèmes similaires, mais aucune réponse vraiment satisfaisante. Ma question est donc la suivante : comment puis-je faire en sorte que mes pages fonctionnent de la même manière dans Safari que dans les autres navigateurs après que l'utilisateur a appuyé sur le bouton "retour" ?

S'il s'agit d'une question stupide, soyez indulgent, javascript est quelque peu nouveau pour moi.

19voto

Lee Kowalkowski Points 6278

La solution iframe de Stefan fonctionne, mais si ce n'est pas assez élégant, je trouve que le JavaScript suivant résout aussi le problème :

window.onunload = function(){};

Autrement dit, si votre menu est en JavaScript, vous préférerez peut-être résoudre ce problème avec JavaScript également.

L'idée de la définition du gestionnaire d'événements de déchargement vient de cet article sur Firefox 1.5 : https://developer.mozilla.org/en/Using_Firefox_1.5_caching .

9voto

Manuel Pardo Points 49

Mettez simplement ceci dans la balise body <body onunload="">

cela forcera safari, chrome, FF à se recharger à chaque fois que vous appuyez sur le bouton "Back".

8voto

Gary Hayes Points 426

Voici une bonne solution pour Mobile Safari :

/*! Reloads page on every visit */
function Reload() {
    try {
        var headElement = document.getElementsByTagName("head")[0];
        if (headElement && headElement.innerHTML)
            headElement.innerHTML += " ";
        } catch (e) {}
    }

    /*! Reloads on every visit in mobile safari */
    if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) {
        window.onpageshow = function(evt) {
            if (evt.persisted) {
                document.body.style.display = "none";
                location.reload();
            }
        };
    }

( source )

Je l'ai modifié selon mes besoins, mais tel quel, il est correct. (écran blanc ennuyeux lors du rafraîchissement si vous ne le modifiez pas).

7voto

olliej Points 16255

@Autodidact : Ce n'est certainement pas une question stupide, chaque fois que le comportement de webkit diffère de celui d'IE et de Firefox, il s'agit d'un bug qui doit être signalé à l'adresse suivante http://bugs.webkit.org (Je le classerais moi-même, mais je serais alors celui qui devrait confirmer le correctif, plutôt que vous, ce qui serait plutôt stupide étant donné que vous êtes la personne qui rencontre ce bug :D). [Edit : Je viens de réaliser que votre exemple sera dans le cache back/forward -- le onload ne se déclenchera pas à nouveau car l'état JS entier sera stocké, il semble peu probable dans ce cas que cela cause un bug, donc lorsque vous déposez un rapport de bug, si possible vous devriez essayer d'inclure le code ou l'url qui échoue].

@Teifon : Um, les ingénieurs d'Apple font presque tout le développement actif de WebKit (WebKit est un framework système MacOS après tout, et apple a commencé le projet (comme un fork de khtml, mais ils sont maintenant substantiellement divergents)), les développeurs non-apple se concentrent presque entièrement sur leurs back et front ends respectifs (eg. gtk, qt, wx) -- si vous regardez à http://trac.webkit.org/ vous pouvez voir que la majorité du travail de développement provient d'apple -- et les irc-ers les plus actifs sont des ingénieurs d'apple, donc je ne comprends vraiment pas comment vous êtes arrivé à la conclusion que webkit est en quelque sorte communautaire alors qu'apple ne l'est pas :D (Désolé pour la longue réponse, je suis juste fatigué de voir cette idée fausse répétée :-/ )

[Edit : @Stefan Koenig Je pense que tout endroit où le comportement de la mise en cache diffère de celui d'IE et de Firefox d'une manière qui casse réellement un site est un bogue].

7voto

Stefan Koenig Points 466

Un iframe résout le problème :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body onload="alert('Hello');">
<a href="http://www.codinghorror.com">Coding Horror</a>
<iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
this prevents back forward cache
</iframe>
</body>
</html>

plus détails

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X