Jak zapobiec buforowaniu zawartości iframe przez przeglądarkę Firefox i Safari?
Mam prostą stronę internetową z ramką iframe prowadzącą do strony w innej witrynie. Zarówno strona zewnętrzna, jak i strona wewnętrzna mają nagłówki odpowiedzi HTTP, aby zapobiec buforowaniu. Kiedy klikam przycisk „Wstecz” w przeglądarce, zewnętrzna strona działa poprawnie, ale bez względu na wszystko przeglądarka zawsze pobiera pamięć podręczną strony w ramce iframe. IE działa dobrze, ale Firefox i Safari sprawiają mi kłopoty.
Moja strona internetowa wygląda mniej więcej tak:
<html>
<head><!-- stuff --></head>
<body>
<!-- stuff -->
<iframe src="webpage2.html?var=xxx" />
<!-- stuff -->
</body>
</html>
var
Zmienna zawsze zmienia. Pomimo faktu, że adres URL elementu iframe uległ zmianie (a zatem przeglądarka powinna wysyłać nowe żądanie do tej strony), przeglądarka po prostu pobiera zawartość pamięci podręcznej.
Zbadałem żądania HTTP i odpowiedzi przesyłane tam iz powrotem i zauważyłem, że nawet jeśli zewnętrzna strona zawiera <iframe src="webpage2.html?var=222" />
, przeglądarka nadal będzie pobierać webpage2.html?var=111
.
Oto, czego próbowałem do tej pory:
- Zmiana adresu URL elementu iframe na losową wartość var
- Dodawanie nagłówków Expires, Cache-Control i Pragma do zewnętrznej strony internetowej
- Dodawanie nagłówków Expires, Cache-Control i Pragma do wewnętrznej strony internetowej
Nie mogę wykonywać żadnych sztuczek JavaScript, ponieważ blokują mnie zasady tego samego pochodzenia.
Kończą mi się pomysły. Czy ktoś wie, jak powstrzymać przeglądarkę przed buforowaniem zawartości iframed?
Aktualizacja
Zainstalowałem Fiddler2 tak, jak Daniel zasugerował wykonanie innego testu i niestety nadal otrzymuję te same wyniki.
Oto test, który przeprowadziłem:
- Strona zewnętrzna generuje liczbę losową przy użyciu
Math.random()
JSP. - Strona zewnętrzna wyświetla losową liczbę na stronie internetowej.
- Strona zewnętrzna wywołuje iframe, przekazując losową liczbę.
- Wewnętrzna strona wyświetla losową liczbę.
Dzięki temu testowi mogę dokładnie zobaczyć, które strony są aktualizowane i które są buforowane.
Test wizualny
Aby przeprowadzić szybki test, wczytuję stronę, przechodzę do innej strony, a następnie naciskam „Wstecz”. Oto wyniki:
Strona oryginalna:
- Strona zewnętrzna: 0.21300034290246206
- Strona wewnętrzna: 0.21300034290246206
Opuszczanie strony, a następnie powrót:
- Strona zewnętrzna: 0.4470929019483644
- Strona wewnętrzna: 0.21300034290246206
To pokazuje, że strona wewnętrzna jest buforowana, mimo że strona zewnętrzna wywołuje ją z innym parametrem GET w adresie URL. Z jakiegoś powodu przeglądarka ignoruje fakt, że element iframe żąda nowego adresu URL; po prostu ładuje stary.
Test skrzypka
Rzeczywiście, Fiddler potwierdza to samo.
(Wczytuję stronę.)
Nazywa się strona zewnętrzna. HTML:
0.21300034290246206
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206" />
http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 .
(Wychodzę ze strony i wracam).
Nazywa się strona zewnętrzna. HTML:
0.4470929019483644
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.4470929019483644" />
http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 .
Cóż, z tego testu wygląda na to, że przeglądarka internetowa nie buforuje strony, ale buforuje adres URL elementu iframe, a następnie wysyła nowe żądanie na ten buforowany adres URL. Jednak nadal nie wiem, jak rozwiązać ten problem.
Czy ktoś ma jakieś pomysły, jak zatrzymać buforowanie adresów URL elementów iframe przez przeglądarkę internetową?
Odpowiedzi:
Ustaw adres URL elementu iframe na stronę w Twojej witrynie, która działa jako serwer proxy do pobierania i zwracania rzeczywistej zawartości elementu iframe. Teraz nie jesteś już związany zasadami tego samego pochodzenia (EDYCJA: nie zapobiega problemowi z buforowaniem iframe).
źródło
To jest błąd w Firefoksie:
https://bugzilla.mozilla.org/show_bug.cgi?id=356558
Wypróbuj to obejście:
źródło
Udało mi się obejść ten błąd, ustawiając unikalny
name
atrybut w ramce iframe - z jakiegoś powodu wydaje się, że powoduje to uszkodzenie pamięci podręcznej. Możesz użyć dowolnych danych dynamicznych jakoname
atrybutu - lub po prostu bieżącego czasu ms lub ns w jakimkolwiek języku szablonów, którego używasz. Jest to ładniejsze rozwiązanie niż powyższe, ponieważ nie wymaga bezpośrednio JS.W moim konkretnym przypadku iframe jest budowany przez JS (ale możesz zrobić to samo przez PHP, Ruby, cokolwiek), więc po prostu używam
Date.now()
:To naprawia błąd w moich testach; prawdopodobnie dlatego, że
window.name
w okienku wewnętrznym się zmienia.źródło
Jak powiedziałeś, problemem nie jest magazynowanie zawartości iframe , ale buforowanie url iframe .
Od września 2018 wydaje się, że problem nadal występuje w przeglądarce Chrome, ale nie w przeglądarce Firefox.
Próbowałem wielu rzeczy (dodanie zmiany parametru GET, wyczyszczenie adresu url iframe w onbeforeunload, wykrycie „przeładowania z pamięci podręcznej” przy użyciu pliku cookie, ustawienie różnych nagłówków odpowiedzi) i oto jedyne dwa rozwiązania, które działały ode mnie:
1- Prosty sposób: stwórz swój iframe dynamicznie z javascript
Na przykład:
2- Zagmatwany sposób
Jak wyjaśniono tutaj , po stronie serwera wyłącz magazynowanie zawartości dla treści, które serwujesz dla elementu iframe LUB strony nadrzędnej (jedno i drugie).
I
Ustaw adres URL elementu iframe z javascript z dodatkowym zmieniającym się parametrem wyszukiwania, na przykład:
(wersja uproszczona, uwaga na inne parametry wyszukiwania)
źródło
Po wypróbowaniu wszystkiego innego (oprócz korzystania z serwera proxy dla zawartości iframe) znalazłem sposób, aby zapobiec buforowaniu zawartości iframe z tej samej domeny :
Użyj
.htaccess
i przepisuj regułę oraz zmieńsrc
atrybut iframe .RewriteRule test/([0-9]+)/([a-zA-Z0-9]+).html$ /test/index.php?idEntity=$1&token=$2 [QSA]
Sposób, w jaki to wykorzystuję, polega na tym, że adres URL elementu iframe wygląda tak:
example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
Gdzie [token] to losowo wygenerowana wartość. Ten adres URL zapobiega buforowaniu elementu iframe, ponieważ token nigdy nie jest taki sam, a element iframe uważa, że to zupełnie inna strona internetowa, ponieważ pojedyncze odświeżenie ładuje zupełnie inny adres URL:
example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
example.com/test/54/d2cc21be7cdcb5a1f989272706de1913.html
oba prowadzą do tej samej strony.
Możesz uzyskać dostęp do ukrytych parametrów adresu URL za pomocą
$_SERVER["QUERY_STRING"]
źródło
Jest to błąd występujący w Firefoksie 3.5.
Spójrz ... https://bugzilla.mozilla.org/show_bug.cgi?id=279048
źródło
Aby element iframe zawsze ładował świeżą zawartość, dodaj aktualną sygnaturę czasową systemu Unix na końcu parametrów GET. Przeglądarka wtedy postrzega to jako „inne” żądanie i szuka nowych treści.
W JavaScript może to wyglądać tak:
źródło
Znalazłem ten problem w najnowszym Chrome, a także w najnowszym Safari na Mac OS X z 17 marca 2016 r. Żadna z powyższych poprawek nie zadziałała, w tym przypisanie src do pustego, a następnie z powrotem do jakiejś witryny lub dodanie jakiś losowo nazwany parametr „nazwa” lub dodanie losowej liczby na końcu adresu URL po krzyżyku lub przypisanie href okna zawartości do src po przypisaniu src.
W moim przypadku było to spowodowane tym, że używałem Javascript do aktualizacji IFRAME i tylko przełączałem hash w adresie URL.
Sposób obejścia problemu w moim przypadku polegał na tym, że utworzyłem tymczasowy adres URL, który miał 0-sekundowe przekierowanie meta do tej innej strony. Dzieje się to tak szybko, że ledwo zauważam migotanie ekranu. Dodatkowo sprawiłem, że kolor tła strony tymczasowej jest taki sam jak na drugiej stronie, dzięki czemu można go zauważyć jeszcze mniej.
źródło
Ustawiam atrybut iframe src później w mojej aplikacji. Aby pozbyć się zawartości pamięci podręcznej wewnątrz iframe na początku aplikacji, po prostu robię:
... gdzieś na początku kodu js (na przykład w module obsługi jquery $ ())
Podziękowania dla http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/
źródło
Miałem też ten problem w 2016 roku z iOS Safari. Wydawało mi się, że zadziałało podanie parametru GET do elementu iframe src i wartości takiej jak ta
<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>
źródło
Czy zainstalowałeś Fiddler2 ?
Pozwoli ci zobaczyć dokładnie, o co proszono, co jest odsyłane, itp. Nie wydaje się prawdopodobne, aby przeglądarka naprawdę trafiła do pamięci podręcznej dla różnych adresów URL.
źródło
Jeśli chcesz naprawdę zwariować, możesz zaimplementować nazwę strony jako dynamiczny adres URL, który zawsze prowadzi do tej samej strony, a nie do opcji zapytania?
Zakładając, że jesteś w biurze, sprawdź, czy na poziomie sieci działa buforowanie. Uwierz mi, jest taka możliwość. Twoi informatycy będą w stanie powiedzieć Ci, czy istnieje infrastruktura sieciowa wokół buforowania HTTP, chociaż ponieważ dzieje się to tylko w przypadku ramki iframe, jest to mało prawdopodobne.
źródło
Czy próbowałeś dodać różne opcje nagłówka HTTP dla no-cache do strony iframe?
źródło