web-dev-qa-db-fra.com

Empêchez le chargement de safari à partir du cache lorsque vous cliquez sur le bouton Précédent

Vous avez un problème avec safari lors du chargement d'anciennes vidéos YouTube lorsque vous cliquez sur le bouton Retour. J'ai essayé d'ajouter onunload = "" (mentionné ici Empêcher le cache sur le bouton de retour dans Safari 5 ) à la balise body mais cela ne fonctionne pas dans ce cas.

Existe-t-il un moyen d'empêcher le chargement safari du cache sur une certaine page?

59
Mark Steggles

Votre problème est dû à cache arrière . Il est censé enregistrer l'état complet de la page lorsque l'utilisateur s'éloigne. Lorsque l'utilisateur revient en arrière, la page du bouton de retour peut être chargée très rapidement à partir du cache. Ceci est différent du cache normal qui ne met en cache que le code HTML.

Lorsque la page est chargée pour bfcache onload, l'événement ne sera pas déclenché. Au lieu de cela, vous pouvez vérifier la propriété persisted de l'événement onpageshow. Il est défini sur false lors du chargement initial de la page. Lorsque la page est chargée à partir de bfcache, elle est définie sur true.

La solution Kludgish consiste à forcer un rechargement lorsque la page est chargée à partir de bfcache.

window.onpageshow = function(event) {
    if (event.persisted) {
        window.location.reload() 
    }
};

Si vous utilisez jQuery, procédez comme suit:

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        window.location.reload() 
    }
});
168
Mika Tuupola

Oui, le navigateur Safari ne gère pas le cache des boutons arrière/avant de la même manière que Firefox et Chrome le fait. En particulier, les iframes comme les vidéos vimeo ou youtube sont à peine mis en cache bien qu'il existe un nouveau iframe.src.

J'ai trouvé trois façons de gérer cela. Choisissez le meilleur pour votre cas. Solutions testées sur Firefox 53 et Safari 10.1

1. Détectez si l'utilisateur utilise le bouton arrière/avant, puis rechargez la page entière ou rechargez uniquement les iframes mis en cache en remplaçant le src

if (!!window.performance && window.performance.navigation.type === 2) {
            // value 2 means "The page was accessed by navigating into the history"
            console.log('Reloading');
            //window.location.reload(); // reload whole page
            $('iframe').attr('src', function (i, val) { return val; }); // reload only iframes
        }

2. recharger la page entière si la page est mise en cache

window.onpageshow = function (event) {
        if (event.persisted) {
            window.location.reload();
        }
    };

. Supprimez la page de l'historique afin que les utilisateurs ne puissent plus la visiter à l'aide des boutons Précédent/Suivant

$(function () {
            //replace() does not keep the originating page in the session history,
            document.location.replace("/Exercises#nocache"); // clear the last entry in the history and redirect to new url
        });
6
Javan R.

Toutes ces réponses sont un peu du piratage. Dans les navigateurs modernes (safari) uniquement sur onpageshow travail de solution,

window.onpageshow = function (event) {
    if (event.persisted) {
        window.location.reload();
    }
};

mais sur les appareils lents, vous verrez parfois pendant une fraction de seconde la vue en cache précédente avant qu'elle ne soit rechargée. La bonne façon de résoudre ce problème consiste à définir correctement Cache-Control sur la réponse du serveur à un soufflet

'Cache-Control', 'no-cache, max-age=0, must-revalidate, no-store'

5
waj-er-rr

Vous pouvez utiliser une ancre et surveiller la valeur de l'emplacement du document href;

Commencer avec http://acme.co/, ajoutez quelque chose à l'emplacement, comme '#b';

Donc, maintenant, votre URL est http://acme.co/#b, lorsqu'une personne appuie sur le bouton de retour, il revient à http://acme.co, et la fonction de vérification d'intervalle voit l'absence de la balise de hachage que nous avons définie, efface l'intervalle et charge l'URL de référence avec un horodatage qui lui est ajouté.

Il y a des effets secondaires, mais je vous laisse les comprendre;)

<script>
document.location.hash = "#b";
var referrer = document.referrer;

// setup an interval to watch for the removal of the hash tag
var hashcheck = setInterval(function(){
    if(document.location.hash!="#b") {

    // clear the interval
    clearInterval(hashCheck);

    var ticks = new Date().getTime();
    // load the referring page with a timestamp at the end to avoid caching
    document.location.href.replace(referrer+'?'+ticks);
    }
},100);
</script>

Ceci n'est pas testé mais cela devrait fonctionner avec un ajustement minimal.

1
L422Y

Tout d'abord, insérez un champ dans votre code:

<input id="reloadValue" type="hidden" name="reloadValue" value="" />

puis exécutez jQuery:

jQuery(document).ready(function()
{
        var d = new Date();
        d = d.getTime();
        if (jQuery('#reloadValue').val().length == 0)
        {
                jQuery('#reloadValue').val(d);
                jQuery('body').show();
        }
        else
        {
                jQuery('#reloadValue').val('');
                location.reload();
        }
});

Le comportement est lié au cache Précédent/Suivant de Safari. Vous pouvez en savoir plus sur la documentation Apple Apple: http://web.archive.org/web/20070612072521/http://developer.Apple.com/internet/ safari/faq.html # anchor5

La propre suggestion de correction d'Apple consiste à ajouter un iframe vide sur votre page:

<iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
    this frame prevents back forward cache
</iframe>

(La réponse acceptée précédente semble également valide, je voulais simplement intégrer la documentation et un autre correctif potentiel)

0
Simon Boudrias