Verhindern Sie das Laden von Safari aus dem Cache, wenn Sie auf die Schaltfläche "Zurück" klicken

74

Beim Laden alter YouTube-Videos beim Klicken auf die Schaltfläche "Zurück" wurde ein Problem mit der Safari behoben. Ich habe versucht, onunload = "" (hier erwähnt Verhindern des Cache auf der Zurück-Schaltfläche in Safari 5 ) zum Body-Tag hinzuzufügen, aber dies funktioniert in diesem Fall nicht.

Gibt es eine Möglichkeit, das Laden von Safari aus dem Cache auf einer bestimmten Seite zu verhindern?

Mark Steggles
quelle
mögliche Kopie der Mobile Safari Zurück-Taste
Mika Tuupola
@ MikaTuupola Antwort sollte als die richtige Antwort markiert werden.
Julien Bérubé
Dies ist das bescheidene Problem, das ich auch aufgrund des gleichen BFCache-Verhaltens auf Safari hatte: stackoverflow.com/questions/40727989/…
juanmirocks
In meinem Fall, als ich nur einige Klassen manipulieren musste, funktionierte der Code in diesem Artikel .
Barna Tekse

Antworten:

191

Ihr Problem wird durch den Back-Forward-Cache verursacht . Es soll den vollständigen Status der Seite speichern, wenn der Benutzer weg navigiert. Wenn der Benutzer mit der Zurück-Schaltfläche zurück navigiert, kann die Seite sehr schnell aus dem Cache geladen werden. Dies unterscheidet sich vom normalen Cache, der nur HTML-Code zwischenspeichert.

Wenn die Seite für das bfcache- onloadEreignis geladen wird, wird dies nicht ausgelöst. Stattdessen können Sie die persistedEigenschaft des onpageshowEreignisses überprüfen . Es wird beim ersten Laden der Seite auf false gesetzt. Wenn die Seite aus dem bfcache geladen wird, wird sie auf true gesetzt.

Die kludgische Lösung besteht darin, ein erneutes Laden zu erzwingen, wenn die Seite aus dem bfcache geladen wird.

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

Wenn Sie jQuery verwenden, gehen Sie wie folgt vor:

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        window.location.reload() 
    }
});
Mika Tuupola
quelle
8
Dies ist die einzige funktionierende Lösung, die ich bisher gefunden habe, aber sie ist ziemlich unvollständig, da die Seite vor dem erneuten Laden noch kurz angezeigt wird und die Lösung durch Deaktivieren von Javascript leicht vereitelt werden kann. Hat es jemand geschafft, eine vollständigere Lösung zu finden?
Luken
Dies scheint nicht auf Chrome für Android zu funktionieren (kein anderer mobiler Browser zu testen, was meine Aussage einschränkt)
Dominique
Für IE 11 musste ich window.location = window.locationstattdessen verwenden window.location.reload(), aus Gründen, von denen ich annehme, dass sie im Nebel der Zeit verloren sind.
Paul D. Waite
Um das Problem mit der Sichtbarkeit der Seite kurz vor dem Auslöser der Onpageshow zu lösen, können Sie das Ereignis onbeforeunload verwenden. Während dieses Ereignisses können Sie die Deckkraft des Körpers auf 0 ändern. Also ja, aber die Seite wird kurz sichtbar sein, aber mit einer Deckkraft von 0. (window.onbeforeunload = () => {document.body.opacity = 0;}). Dies funktioniert mit Safari 11.
Kamen Stoykov
Funktioniert nicht in Chrome (Desktop auch) wegen eines Fehlers bugs.chromium.org/p/chromium/issues/…
lofihelsinki
9

Alle diese Antworten sind ein bisschen Hack. In modernen Browsern (Safari) nur auf onpageshowLösungsarbeit,

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

Bei langsamen Geräten wird jedoch manchmal für einen Sekundenbruchteil die vorherige zwischengespeicherte Ansicht angezeigt, bevor sie erneut geladen wird. Der richtige Weg, um dieses Problem zu lösen, besteht darin, die Cache-Steuerung für die Serverantwort auf einen Balg richtig einzustellen

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

waj-er-rr
quelle
Vielen Dank, der Header scheint zu funktionieren und viel schöner zu sein als die JS-Lösungen.
Andy
Ich habe diesen Code in den HEADER eingefügt und jetzt führt Safari auf dem iPhone JS- und JQuery-Code aus, wenn Sie über den Zurück-Button zu dieser Seite zurückkehren. Danke!
Al-Noor Ladhani
6

Ja, der Safari-Browser verarbeitet den Cache für Zurück- / Vorwärtsschaltflächen nicht wie Firefox und Chrome. Insbesondere iframes wie vimeo oder youtube videos werden kaum zwischengespeichert, obwohl es eine neue iframe.src gibt.

Ich habe drei Möglichkeiten gefunden, damit umzugehen. Wählen Sie das Beste für Ihren Fall. Auf Firefox 53 und Safari 10.1 getestete Lösungen

1. Ermitteln Sie, ob der Benutzer die Schaltfläche Zurück / Vorwärts verwendet, und laden Sie dann die gesamte Seite neu oder laden Sie nur die zwischengespeicherten Iframes neu, indem Sie den src ersetzen

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. Laden Sie die gesamte Seite neu, wenn die Seite zwischengespeichert ist

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

3. Entfernen Sie die Seite aus dem Verlauf, damit Benutzer die Seite nicht über die Schaltflächen Zurück / Vorwärts erneut aufrufen können

$(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
        });
Javan R.
quelle
1

Sie können einen Anker verwenden und den Wert des Speicherorts des Dokuments href beobachten.

Beginnen Sie mit http://acme.co/, hängen Sie etwas an den Speicherort an, z. B. '#b';

So, jetzt Ihre URL ist http://acme.co/#b, wenn eine Person die Zurück - Taste trifft, geht es zurück zu http://acme.co, und das Intervall - Check - Funktion sieht das Fehlen des Hash - Tag setzen wir, löscht das Intervall, und lädt die Referrer - URL mit einem Zeitstempel angehängt dazu.

Es gibt einige Nebenwirkungen, aber ich überlasse es Ihnen, diese herauszufinden;)

<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>

Dies ist nicht getestet, sollte aber mit minimalen Anpassungen funktionieren.

L422Y
quelle
2
lustig, die einzige noch funktionierende lösung bekommt eine negative
bewertung
1

Das Verhalten hängt mit dem Back / Forward-Cache von Safari zusammen. Informationen dazu finden Sie in der entsprechenden Apple-Dokumentation: http://web.archive.org/web/20070612072521/http://developer.apple.com/internet/safari/faq.html#anchor5

Apples eigener Fixvorschlag besteht darin, Ihrer Seite einen leeren Iframe hinzuzufügen:

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

(Die zuvor akzeptierte Antwort scheint ebenfalls gültig zu sein, wollte nur die Dokumentation und eine weitere mögliche Lösung einbinden.)

Simon Boudrias
quelle
Die beste Lösung, die ich gefunden habe, war hier: stackoverflow.com/questions/20899274/…
i_a
0

Fügen Sie zunächst ein Feld in Ihren Code ein:

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

Führen Sie dann jQuery aus:

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();
        }
});
Ivan Laharnar mink.si
quelle
0

Es gibt viele Möglichkeiten, den bfcache zu deaktivieren. Am einfachsten ist es, einen "Entlade" -Handler festzulegen. Ich denke, es war ein großer Fehler, die Handler 'entladen' und 'vor dem Entladen' den bfcache deaktivieren zu lassen, aber genau das haben sie getan (wenn Sie einen dieser Handler haben möchten und den bfcache trotzdem funktionieren lassen möchten, können Sie den Handler vor dem Entladen entfernen der Beforeunload-Handler).

window.addEventListener('unload', function() {})

Lesen Sie hier mehr:

https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching

BT
quelle
0

Ich hatte das gleiche Problem mit der Verwendung von 3 verschiedenen Ankerlinks zur nächsten Seite. Wenn Sie von der nächsten Seite zurückkehren und einen anderen Anker auswählen, hat sich der Link nicht geändert.

so hatte ich

<a href="https://www.example.com/page-name/#house=house1">House 1</a>
<a href="https://www.example.com/page-name/#house=house2">View House 2</a>
<a href="https://www.example.com/page-name/#house=house3">View House 3</a>

Gewechselt zu

<a href="/page-name#house=house1">House 1</a>
<a href="/page-name#house=house2">View House 2</a>
<a href="/page-name#house=house3">View House 3</a>

Auch zur Sicherheit verwendet:

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

// JQuery
$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        window.location.reload() 
    }
});

Keine der online gefundenen Lösungen zum Entladen, Neuladen und Neuladen (true) funktionierte einzeln nicht. Hoffe das hilft jemandem mit der gleichen Situation.

user3615851
quelle