Kann ich window.location.replace in einem Iframe verwenden?


15

Wir können verwenden window.location.replacezu vermeiden , Geschichte und Ziel auf Seite Anker ohne Seite neu geladen, aber nicht in iframes?

Das Problem ist eine CSP-Verletzung (Content Security Policy), deren Status script-src 'unsafe-inline'aktiviert sein muss. Außer ich habe keinen CSP definiert, und selbst wenn ich einen definiere und zulasse script-src 'unsafe-inline', gibt es immer noch den gleichen Verstoßfehler. Gleiches Ergebnis in ie11 / chrome / ff.

Iframe in derselben Domain (im selben Verzeichnis).

  1. Zielen Sie auf den Iframe in der Konsole und verwenden Sie ihn window.location.replace('/samepage.html#onpage_anchor')in der Konsole.
  2. Es klappt. Es zielt auf den On-Page-Anker ab, ohne die Seite neu zu laden und ohne Verlauf.
  3. Setzen Sie den gleichen Code inline auf Ankerlinks und es funktioniert.
  4. Verwenden Sie denselben Code in einem externen Skript, und erhalten Sie den Fehler "csp-Verletzung". Dies funktioniert gut, wenn nicht in einem Iframe.

Ich versuchte , einen CSP zu schaffen , der Aktion zu ermöglichen, aber nicht einmal die meisten permissiven Inhalt Sicherheitsrichtlinien möglich würden es erlauben.


Bearbeiten: Also habe ich Beispiele für Plunker zusammengestellt, die mehrere Dateien zulassen, damit ich geeignete hrefs verwenden kann, die auf die übergeordneten / untergeordneten Seiten verweisen.

Hinweise zu den Plunker-Beispielen:

  1. Das Problem wird in diesen Beispielen nicht reproduziert. Das Skript funktioniert auch im Iframe einwandfrei. Der gleiche Code funktioniert jedoch nicht auf meinem lokalen Server oder wenn ich ihn live auf einem VPS ausführe.

  2. Ich vermute, dass die CSP-Verletzung beim Plunker nicht ausgelöst wird, weil der Plunker dem Browser Inhalte über eine Art Abstraktionsschicht präsentiert.

  3. Wenn Sie zum ersten Mal auf die Akkordeon-Links im übergeordneten Element klicken, wird eine Aktualisierung durchgeführt. Dies liegt daran, dass die Art und Weise, wie die Seite anfänglich geladen wird, nicht auf index.html verweist. Nachfolgende Klicks funktionieren wie erwartet ohne erneutes Laden der Seite. Kein Problem im iframe, da es zunächst auf child.html verweist

  4. Dies sind gute Beispiele, um den Code zu zeigen, ohne dass Änderungen erforderlich sind, damit er funktioniert (wie bei der Notwendigkeit, die hrefs zu ändern, damit sie in den unten genannten Stackoverflow-Snippets funktionieren). Es ist auch gut, da es zeigt, dass das Javascript so funktioniert, wie es sollte. Aber es zeigt nicht das eigentliche Problem. Sie müssen es weiterhin in Ihren Editor laden und auf einem lokalen Server oder einer Live-Hosting-Umgebung ausführen, um das eigentliche Problem zu erkennen.

Plunker-Beispiele

Mit Skript: Ohne Geschichte
Ohne Skript: Mit Geschichte


Vereinfachtes Codebeispiel

Einfaches Akkordeon mit einem Eintrag. Ausreichend, um das Problem zu reproduzieren.

Durch Klicken auf Öffnen / Schließen wird das Akkordeon erweitert / reduziert, kein JS erforderlich. Der JS sollte genau das Gleiche tun, aber ohne Geschichte. Funktioniert gut, aber nicht in einem Iframe.

Code-Snippet-Notizen:

  1. Sie können das Snippet ausführen, um eine Vorstellung davon zu bekommen, was ich beschreibe, aber es zeigt das Problem nicht wirklich.

  2. Das Snippet verhält sich nicht wie in einem echten Browser, das Javascript funktioniert nicht.

  3. Das Snippet zeigt den Code an, sollte jedoch in einem Iframe ausgeführt werden, um das Problem zu erkennen. Führen Sie es außerhalb eines Iframes aus, um den Unterschied und die Funktionsweise zu sehen .

  1. Wegen , wie die Verbindungen arbeiten mit dem JS (die gesamte URL zu ersetzen) sie tatsächlich muss so sein und href="https://stackoverflow.com/thispage.html#ac1"nicht nur , href="#ac1"wie sie im Snippet angezeigt (kann die tatsächliche HTML - Seite im Snippet nicht Ziel). Wenn Sie dies in Ihrem Editor versuchen (bitte tun Sie dies), denken Sie daran, die Links in dieses Format zu ändern,this_document.html#anchor damit sie immer noch dieselben Seitenanker sind, aber die page.html ist im Link enthalten.


Das Skript

$(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);

    });

Dies ist sehr einfach:
1. Die Funktion acAnch nimmt das hrefAttribut und legt es dort ab window.location.replace().
2. Achten Sie auf Klicks auf Anker im Akkordeon, um die acAnch-Funktion auszuführen.

Das Skript wird also nur ausgeführt window.location.replace('/this_same_page.html#on_page_anchor')

Wenn Sie das in die Konsole legen, funktioniert es, keine CSP-Verletzung. Das Ausführen über ein externes Skript funktioniert jedoch nicht.

Inline auf den Links funktioniert gut:

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

Das auf die jeweiligen Links zu setzen funktioniert perfekt , aber ich bevorzuge es wirklich , kein solches Inline-Skript zu verwenden. Es muss eine Möglichkeit geben, dies mit einem externen Skript zu tun .

Ich habe versucht, das Javascript auf dem übergeordneten Element anstatt im Iframe auszuführen (natürlich mit Änderungen, um die Links innerhalb des untergeordneten Elements auszuwählen). Gleiches CSP-Fehlerergebnis.


Warum mache ich das?

Nun, die Seite ist viel komplexer als das Beispiel. Anker in Iframes funktionieren einwandfrei, fügen jedoch den Verlauf hinzu. Wenn Sie den obigen Code ohne Javascript ausführen (oder nur das Snippet ausführen), das Akkordeon einige Male öffnen und schließen und die Zurück-Taste verwenden, werden die Öffnungs- / Schließzustände durchlaufen.

Ich hätte nichts gegen den Verlauf, aber wenn er sich in einem Iframe befindet, wenn Sie die übergeordnete Seite verlassen und dann darauf zurückkommen, ist der Verlauf im Iframe unterbrochen. Beim Zurückgehen werden die Akkordeonzustände nicht mehr durchlaufen, sondern der Iframe wird immer wieder neu geladen. Anfänglich verursachen die Anker keine Iframe-Neuladungen, sondern durchlaufen lediglich den Akkordeonstatusverlauf, der einwandfrei funktioniert, bis Sie die Seite verlassen und zurückkehren. Dann geht zurück nicht mehr durch die Akkordeonzustände, sondern nur durch einen Stapel identischer Iframe-Nachladungen. Es ist sehr benutzerunfreundliches Verhalten.

Ich muss location.replace nicht verwenden, wenn es eine andere Methode gibt, die funktioniert. Ich habe jedoch viele andere Ansätze ausprobiert und festgestellt, dass Methoden, die dasselbe Ergebnis erzielen können, im Allgemeinen zu demselben Fehler führen.

Das Ziel besteht einfach darin , die Ankerlinks auf der Seite ohne erneutes Laden und ohne Verlauf innerhalb eines Iframes zu aktivieren .

Das Inline-Skript funktioniert. Können wir es in einer externen .js-Datei zum Laufen bringen?


Versuchst du nur den Anker zu erreichen? wenn ja, <a href="#ac0" class="ac-close">Close</a>sollte funktionieren.
Dementic

Okay, ich habe Beispiele für Plunker eingerichtet. Leider wird das Problem nicht auf Plunker reproduziert. Vielmehr funktioniert das Skript auch in einem Iframe einwandfrei. mit Skript - keine Geschichte und ohne Skript hat Geschichte . Kleines Problem am Plunker; Akkordeon-Links auf dem übergeordneten Element führen nur beim ersten Klicken zu einer Seitenaktualisierung (anfänglich plunk-Ladevorgänge ohne index.html-Referenz, sodass sie nach dem ersten Klick wie erwartet ohne erneutes Laden der Seite funktionieren). Kein Problem für den Iframe, da er mit der Datei child.html src geladen wird.
Veneseme Tyras

Zumindest mit den Plunker-Beispielen können Sie den vollständigen Code sehen und sehen, wie er funktionieren sollte. Es funktioniert jedoch nicht auf meinem lokalen Server oder wenn ich es live auf einem VPS ausführe. Ich werde die Frage mit den Plunker-Links und Informationen aktualisieren.
Veneseme Tyras

1
Ich habe Ihren Beispielcode auf meinen Server gebracht, er funktioniert einwandfrei. Dann habe ich aus Ihrem Beispiel ein neues Plunker-Beispiel erstellt. Plnkr.co/edit/V3kx7LQbTppaQ6V06uZp?p=preview funktioniert ebenfalls einwandfrei . Kein CSP-Fehlerergebnis.
Denker

Ja, gut, es funktioniert gut mit dem Plunker, den ich auch gemacht habe. Ich bin allerdings gespannt, wie es auf Ihrem Server funktioniert, da ich nach Ihrem Kommentar dreimal überprüft habe und es nicht auf meinem Live-Server oder auf meinem lokalen Server zum Laufen bringen kann.
Veneseme Tyras

Antworten:



0

Sie können CSS anstelle des HTML-Iframe-Tags verwenden, da das Iframe-Tag in HTML entfernt wird


Schauen Sie sich noch einmal an, wie man antwortet . Wie genau würden sie dieses Problem mithilfe von CSS lösen?
Camille
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.