Czy mogę użyć window.location.replace w ramce iframe?


15

Możemy użyć, window.location.replaceaby ominąć historię i celować w kotwice na stronie bez przeładowań strony, ale nie w ramkach iframe?

Problemem jest naruszenie CSP (polityka bezpieczeństwa treści), które script-src 'unsafe-inline'muszą być włączone. Tyle że nie mam zdefiniowanego CSP, a nawet jeśli go zdefiniuję i pozwolę, script-src 'unsafe-inline'że nadal daje ten sam błąd naruszenia. Ten sam wynik w ie11 / chrome / ff.

Element iframe w tej samej domenie (w tym samym katalogu).

  1. Skieruj ramkę iframe w konsoli i użyj window.location.replace('/samepage.html#onpage_anchor')w konsoli.
  2. to działa. Kieruje na kotwicę na stronie bez ponownego ładowania strony i bez historii.
  3. Umieść ten sam kod w linii na linkach zakotwiczenia i działa.
  4. Użyj tego samego kodu w skrypcie zewnętrznym, uzyskaj błąd naruszenia csp. Działa to dobrze, jeśli nie w ramce iframe.

Próbowałem tworzenia CSP , aby umożliwić działanie, ale nie nawet te najbardziej liberalne zasady zabezpieczeń zawartości możliwe by to umożliwić.


Edycja: więc zestawiłem przykłady na temat narzędzia plunker, które pozwala na wiele plików, aby móc użyć odpowiednich hrefów, które odwołują się do stron nadrzędnych / podrzędnych.

Uwagi na temat przykładów plunkera:

  1. Problem nie został odtworzony w tych przykładach. Skrypt działa doskonale, nawet w ramce iframe. Jednak ten sam kod nie działa na moim serwerze lokalnym lub po uruchomieniu go na żywo na VPS.

  2. Podejrzewam, że naruszenie CSP nie jest wywoływane przez plunker, ponieważ plunker przedstawia zawartość przeglądarce za pomocą pewnego rodzaju warstwy abstrakcji.

  3. Pierwsze kliknięcie łączy akordeonu w rodzicu powoduje odświeżenie. Jest tak, ponieważ sposób, w jaki strona początkowo się ładuje, nie odwołuje się do index.html. Kolejne kliknięcia działają zgodnie z oczekiwaniami bez ponownego ładowania strony. Nie stanowi to problemu w ramce iframe, ponieważ początkowo odnosi się do child.html

  4. Są to dobre przykłady pokazania kodu bez konieczności wprowadzania zmian, aby działał (jak potrzeba zmiany hrefów, aby działały we fragmentach przepełnienia stosu, wymienionych poniżej). Jest również dobry, ponieważ pokazuje javascript działający tak, jak powinien. Ale to nie pokazuje rzeczywistego problemu. Nadal będziesz musiał załadować go do edytora i uruchomić na lokalnym serwerze lub na żywo, aby zobaczyć prawdziwy problem.

Przykłady plunkera

Ze skryptem: Bez historii
Bez skryptu: Z historią


Przykład kodu uproszczonego

Prosty akordeon z jednym wejściem. Wystarczające do odtworzenia problemu.

Kliknięcie przycisku otwórz / zamknij spowoduje rozwinięcie / zwinięcie akordeonu, nie wymaga JS. JS powinien zrobić dokładnie to samo, ale bez historii. Działa dobrze, ale nie w ramce iframe.

Uwagi do fragmentu kodu:

  1. Możesz uruchomić fragment kodu, aby zorientować się, co opisuję, ale tak naprawdę nie pokazuje on problemu.

  2. Fragment kodu nie działa tak, jak w prawdziwej przeglądarce, JavaScript nie działa.

  3. Fragment pokazuje kod, ale należy go uruchomić w elemencie iframe, aby zobaczyć problem. Uruchom go poza ramką iframe, aby zobaczyć różnicę i sposób działania.

  1. Ze względu na to, w jaki sposób łącza działają z JS (zastępując cały adres URL), tak naprawdę muszą być takie, href="https://stackoverflow.com/thispage.html#ac1"a nie tylko href="#ac1"takie, jakie pojawiają się we fragmencie (nie mogą być kierowane na rzeczywistą stronę HTML w fragmencie). Więc jeśli spróbujesz tego w swoim edytorze (zrób to), pamiętaj o zmianie linków do tego formatu, this_document.html#anchor aby nadal były tymi samymi kotwicami strony, ale page.html jest zawarty w linku.


Scenariusz

$(document).ready(function() {

      // anchor links without history
      $.acAnch = function(event) {
        event.preventDefault();
        var anchLnk = $(event.target);
        var anchTrgt = anchLnk.attr('href');
        window.location.replace(anchTrgt);
      }
      // listen for anchor clicks
      $('.accordion').on('click', 'a', $.acAnch);

    });

Jest to bardzo proste:
1. Funkcja acAnch bierze hrefatrybut i upuszcza go window.location.replace().
2. Nasłuchuj kliknięć zakotwiczeń w akordeonie, aby uruchomić funkcję acAnch.

Wszystko, co robi skrypt, jest uruchamiane window.location.replace('/this_same_page.html#on_page_anchor')

Jeśli umieścisz to w konsoli, będzie działać, bez naruszenia CSP. Ale uruchomienie go z zewnętrznego skryptu nie działa.

Inline na linkach działa dobrze:

onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"

Umieszczenie tego w odpowiednich linkach działa idealnie , ale naprawdę wolę nie używać takiego wbudowanego skryptu. Musi istnieć sposób na to za pomocą zewnętrznego skryptu.

Próbowałem uruchomić javascript na obiekcie nadrzędnym zamiast w ramce iframe (oczywiście z modyfikacjami umożliwiającymi wybór łączy w obrębie potomka). Ten sam wynik błędu CSP.


Dlaczego to robię?

Cóż, strona jest znacznie bardziej złożona niż przykład. Zakotwiczenia w elementach iframe działają dobrze, ale dodają historię. Jeśli uruchomisz powyższy kod bez javascript (lub po prostu uruchomisz fragment kodu), otworzysz i zamkniesz akordeon kilka razy, a następnie użyjesz przycisku Wstecz, nastąpi powrót do stanu otwartego zamknięcia.

Nie miałbym nic przeciwko historii, ale jeśli jest w ramce iframe, kiedy opuścisz stronę nadrzędną, a następnie do niej wrócisz, historia w ramce iframe jest zepsuta. Cofanie się nie wraca już przez stany akordeonu, ale po prostu ciągle ładuje iframe. Początkowo kotwice nie powodują przeładowania iframe, a jedynie przechodzą przez historię stanu akordeonu, która działa dobrze, dopóki nie opuścisz strony i nie wrócisz. Potem powrót nie przechodzi już przez stany akordeonu, ale po prostu przechodzi przez stos identycznych przeładowań iframe. Jest to bardzo nieprzyjazne zachowanie użytkownika.

Nie muszę używać location.replace, jeśli istnieje inna metoda, która będzie działać. Próbowałem jednak wielu innych podejść i odkryłem, że metody, które mogą osiągnąć ten sam wynik, generalnie powodują ten sam błąd.

Celem jest po prostu aktywowanie linków zakotwiczenia na stronie bez ponownego ładowania i bez historii w ramce iframe.

Skrypt wbudowany działa. Czy możemy sprawić, by działał w zewnętrznym pliku .js?


próbujesz po prostu dotrzeć do kotwicy? jeśli tak, <a href="#ac0" class="ac-close">Close</a>powinno działać.
Dementyczny

Ok, ustawiam przykłady na plunker. Niestety problem ten nie jest odtwarzany na plunkerze. Skrypt działa raczej dobrze, nawet w ramce iframe. ze skryptem - bez historii i bez skryptu ma historię . Drobny problem dotyczący plunkera; linki harmonijkowe na obiekcie nadrzędnym powodują odświeżenie strony, tylko po pierwszym kliknięciu (początkowo załaduj ładunki bez odwołania do index.html, więc po pierwszym kliknięciu działa zgodnie z oczekiwaniami, bez przeładowywania strony). Nie stanowi to problemu dla elementu iframe, ponieważ jest on ładowany z child.html src.
Veneseme Tyras,

Więc przynajmniej z przykładami plunkera możesz zobaczyć pełny kod i zobaczyć, jak powinien on działać. Nie działa to jednak na moim lokalnym serwerze lub po uruchomieniu na żywo na VPS. Zaktualizuję pytanie za pomocą linków i informacji plunker.
Veneseme Tyras,

1
Wziąłem twój przykładowy kod na mój serwer, to działa dobrze, a następnie utworzyłem nowe przykłady plunkera z twojego przykładu plnkr.co/edit/V3kx7LQbTppaQ6V06uZp?p=preview to również działa dobrze. Brak wyniku błędu CSP.
Myśliciel

Tak, dobrze działa również na plunkerze, który zrobiłem. Jestem ciekawy, jak to działa na twoim serwerze, ponieważ po twoim komentarzu potrójnie sprawdziłem i nie mogę zmusić go do działania na moim serwerze na żywo lub na serwerze lokalnym.
Veneseme Tyras,

Odpowiedzi:



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.