Zapobieganie buforowaniu iframe w przeglądarce


86

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>

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

  1. Strona zewnętrzna generuje liczbę losową przy użyciu Math.random()JSP.
  2. Strona zewnętrzna wyświetla losową liczbę na stronie internetowej.
  3. Strona zewnętrzna wywołuje iframe, przekazując losową liczbę.
  4. 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ą?


11
+1 - Twoje pismo tak dobrze oddaje ból.
nickf

1
Dziękuję za bardzo szczegółowe wyjaśnienie problemu, jest to w 100% dokładnie to, czego doświadczam z witryną. Minęło siedem lat, a raport o błędzie Firefoksa jest nadal obecny.
Scuzzy

Odpowiedzi:


-3

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


41
nie zapobiega to pamięci podręcznej.
baash05,

@ baash05 Nigdy nie twierdziłem, że tak; Powiedziałem, że unika polityki tego samego pochodzenia.
kmoser

1
To prawda, ale tytuł op brzmi „Zapobieganie buforowaniu iframe w przeglądarce” i jeśli twoja odpowiedź nie zapobiega buforowaniu iframe w przeglądarce, to tak naprawdę nie jest odpowiedź. Warto wiedzieć, ale nadal nie jest to dobra rada dla kogoś, kto chce zapobiec buforowaniu.
baash05

OP szukał rozwiązania problemu buforowania i uniknięcia zasad tego samego pochodzenia. Częściowa odpowiedź jest lepsza niż żadna :)
kmoser

2
toast zawsze spada
jamą w

58

To jest błąd w Firefoksie:

https://bugzilla.mozilla.org/show_bug.cgi?id=356558

Wypróbuj to obejście:

<iframe src="webpage2.html?var=xxx" id="theframe"></iframe>

<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>

3
Dzisiaj 27.2.2014 tak się cieszę, że znalazłem ten wątek, pomyślałem, że można go rozwiązać przez brak buforowania po stronie serwera. FF 27 nadal ma ten błąd.
Robert

7
7.8.2014 - 8 lat później i nadal nie zostało naprawione.
Łukasz Zaroda

Dotyczy to również atrybutu srcdoc, tak dziwne ... Tak wspaniale, że to znalazłem.
elundmark

2
Znalazłem ten sam problem z pamięcią podręczną w Chrome i dwa wiersze JavaScript go rozwiązały. Dziękuję Ci!
Thorn

2
Wow, miałem dokładnie ten sam problem. Był specyficzny dla Firefoksa - działał dobrze w IE, Chrome itp. Dzięki @caleb. Nie mogę uwierzyć, że to trwało tak długo.
Voodoo,

32

Udało mi się obejść ten błąd, ustawiając unikalny nameatrybut w ramce iframe - z jakiegoś powodu wydaje się, że powoduje to uszkodzenie pamięci podręcznej. Możesz użyć dowolnych danych dynamicznych jako nameatrybutu - 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():

return '<iframe src="' + src + '" name="' + Date.now() + '" />';

To naprawia błąd w moich testach; prawdopodobnie dlatego, że window.namew okienku wewnętrznym się zmienia.


2
Ta odpowiedź działa w przeglądarkach Chrome, Firefox i Safari od końca 2015 r.
rovermicrover

13

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:

const iframe = document.createElement('iframe')
iframe.id = ...
...
iframe.src = myIFrameUrl 
document.body.appendChild(iframe)

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:

const url = myIFrameUrl + '?timestamp=' + new Date().getTime()
document.getElementById('my-iframe-id').src = url

(wersja uproszczona, uwaga na inne parametry wyszukiwania)


5

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 .htaccessi przepisuj regułę oraz zmień srcatrybut 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"]


1
Pracował dla mnie - dzięki!
Quinn Finney

@QuinnFinney Cieszę się, że to było przydatne dla kogoś innego. Rozwiązanie tego problemu zajęło mi kilka dni :)
Jeff Noel

Tak, ja też! hahaha
Quinn Finney


3

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:

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;

3

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.



0

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>


-1

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.


1
Dzięki za wskazówkę dotyczącą Fiddler2. Teraz wiem, że przeglądarka nie buforuje zawartości iframe; po prostu buforuje adres URL elementu iframe. Jednak nadal jestem zakłopotany i nie mam pojęcia, dlaczego przeglądarka miałaby zignorować adres URL elementu iframe nowej strony i po prostu użyć starego adresu URL.
JR.

-1

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.


-2

Czy próbowałeś dodać różne opcje nagłówka HTTP dla no-cache do strony iframe?


Tak. Wypróbowałem dyrektywy no-cache zarówno w nagłówkach HTTP, jak i w metatagach na każdej stronie.
JR.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.