Puis-je utiliser window.location.replace dans un iframe?


15

Nous pouvons utiliser window.location.replacepour éviter l'historique et pour cibler les ancres sur la page sans rechargement de page, mais pas dans les iframes?

Le problème est une violation CSP (Content Security Policy), dont les états script-src 'unsafe-inline'doivent être activés. Sauf que je n'ai pas de CSP défini, et même si j'en définis un et que script-src 'unsafe-inline'je l' autorise, il donne toujours la même erreur de violation. Même résultat dans ie11 / chrome / ff.

Iframe sur le même domaine (dans le même répertoire).

  1. Ciblez l'iframe dans la console et utilisez-la window.location.replace('/samepage.html#onpage_anchor')dans la console.
  2. Ça marche. Il cible l'ancre sur la page sans recharger la page et sans historique.
  3. Mettez le même code en ligne sur les liens d'ancrage et cela fonctionne.
  4. Utilisez le même code dans un script externe, obtenez l' erreur de violation csp. Cela fonctionne bien sinon dans un iframe.

J'ai essayé de créer un CSP pour autoriser l'action, mais même les politiques de sécurité de contenu les plus permissives possibles ne le permettraient pas.


Edit: j'ai donc rassemblé des exemples sur plunker qui autorise plusieurs fichiers afin que je puisse utiliser des hrefs appropriés qui référencent les pages parent / enfant.

Remarques sur les exemples de plunker:

  1. Le problème n'est pas reproduit dans ces exemples. Le script fonctionne parfaitement, même dans l'iframe. Cependant, le même code ne fonctionne pas sur mon serveur local ou lorsque je l'exécute en direct sur un VPS.

  2. Je soupçonne que la violation du CSP ne se déclenche pas sur plunker parce que ce dernier présente du contenu au navigateur via une sorte de couche d'abstraction.

  3. La première fois que vous cliquez sur les liens accordéon dans le parent, cela provoque une actualisation. En effet, la façon dont la page se charge initialement ne fait pas référence à index.html. Les clics suivants fonctionnent comme prévu sans rechargement de page. Pas un problème dans l'iframe car il fait initialement référence à child.html

  4. Ce sont de bons exemples pour montrer le code sans nécessiter de modifications pour le faire fonctionner (comme dans la nécessité de changer les hrefs pour les faire fonctionner dans les extraits de stackoverflow, mentionnés ci-dessous). Il est également bon car il montre que le javascript fonctionne comme il se doit. Mais cela ne montre pas le problème réel. Vous devrez toujours le charger dans votre éditeur et l'exécuter sur un serveur local ou un environnement d'hébergement en direct pour voir le vrai problème.

Exemples Plunker

Avec script: Sans histoire
Sans script: Avec histoire


Exemple de code simplifié

Accordéon simple avec une entrée. Suffisant pour reproduire le problème.

Cliquez sur ouvrir / fermer pour développer / réduire l'accordéon, aucun JS n'est requis. Le JS devrait faire exactement la même chose mais sans historique. Fonctionne bien, mais pas dans un iframe.

Notes d'extrait de code:

  1. Vous pouvez exécuter l'extrait de code pour avoir une idée de ce que je décris, mais cela ne démontre pas réellement le problème.

  2. L'extrait ne se comporte pas comme il le ferait dans un vrai navigateur, le javascript ne fonctionne pas.

  3. L'extrait montre le code, mais il doit être exécuté dans un iframe pour voir le problème. Exécutez-le en dehors d'un iframe pour voir la différence et comment cela devrait fonctionner.

  1. En raison de la façon dont les liens fonctionnent avec le JS (en remplaçant l'URL entière), ils doivent en fait être comme ceci href="https://stackoverflow.com/thispage.html#ac1"plutôt que href="#ac1"tels qu'ils apparaissent dans l'extrait de code (ne peuvent pas cibler la page HTML réelle dans l'extrait de code). Donc, si vous essayez cela dans votre éditeur (veuillez le faire), n'oubliez pas de modifier les liens vers ce format this_document.html#anchor afin qu'ils soient toujours les mêmes ancres de page, mais le page.html est inclus dans le lien.


Le scénario

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

    });

C'est très simple:
1. La fonction acAnch prend l' hrefattribut et le dépose dans window.location.replace().
2. Écoutez les clics sur les ancres dans l'accordéon pour exécuter la fonction acAnch.

Donc, tout le script est exécuté window.location.replace('/this_same_page.html#on_page_anchor')

Si vous mettez cela dans la console, cela fonctionne, aucune violation CSP. Mais l'exécuter à partir d'un script externe ne fonctionne pas.

Inline sur les liens fonctionne bien:

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

Mettre cela sur les liens respectifs fonctionne parfaitement , mais je préfère vraiment ne pas utiliser de script en ligne comme ça. Il doit y avoir un moyen de le faire avec un script externe.

J'ai essayé d'exécuter le javascript sur le parent plutôt que dans l'iframe (avec des modifications pour sélectionner les liens au sein de l'enfant bien sûr). Même résultat d'erreur CSP.


Pourquoi est-ce que je fais cela?

Eh bien, le site est beaucoup plus complexe que l'exemple. Les ancres dans les iframes fonctionnent bien mais elles ajoutent de l'histoire. Si vous exécutez le code ci-dessus sans le javascript (ou exécutez simplement l'extrait), ouvrez et fermez l'accordéon plusieurs fois et utilisez le bouton de retour, il reviendra à travers les états de fermeture ouverts.

Cela ne me dérangerait pas de l'historique, mais s'il se trouve dans un iframe, lorsque vous quittez la page parent et que vous y revenez, l'historique de l'iframe est rompu. Revenir en arrière ne revient plus à travers les états de l'accordéon, mais continue simplement à recharger l'iframe. Initialement, les ancres ne provoquent pas de rechargements iframe, mais parcourent simplement l'historique de l'état de l'accordéon, qui fonctionne correctement, jusqu'à ce que vous quittiez la page et reveniez. Ensuite, le retour ne passe plus par les états de l'accordéon, mais passe simplement par une pile de recharges iframe identiques. C'est un comportement très hostile aux utilisateurs.

Je n'ai pas besoin d'utiliser location.replace s'il existe une autre méthode qui fonctionnera. J'ai essayé de nombreuses autres approches et j'ai trouvé que les méthodes qui peuvent atteindre le même résultat entraînent généralement la même erreur.

Le but est simplement d' activer les liens d'ancrage sur la page sans rechargement, et sans historique, à l' intérieur d'un iframe.

Le script en ligne fonctionne. Pouvons-nous le faire fonctionner dans un fichier .js externe?


essayez-vous juste d'atteindre l'ancre? si oui, <a href="#ac0" class="ac-close">Close</a>devrait fonctionner.
Dementic

D'accord, je configure des exemples sur plunker. Malheureusement, le problème n'est pas reproduit sur plunker. Au contraire, le script fonctionne bien, même dans un iframe. avec script - sans historique et sans script a historique . Problème mineur sur plunker; les liens en accordéon sur le parent provoquent une actualisation de la page, uniquement la première fois que vous cliquez dessus (initialement les charges de plunk sans référence index.html, donc après le premier clic, cela fonctionne comme prévu, sans rechargement de page). Pas un problème pour l'iframe car il est chargé avec le src child.html.
Veneseme Tyras

Donc, au moins avec les exemples de plunker, vous pouvez voir le code complet et voir comment cela devrait fonctionner. Cependant, cela ne fonctionne pas sur mon serveur local ou lorsque je l'exécute en direct sur un VPS. Je mettrai à jour la question avec les liens et les informations du plunker.
Veneseme Tyras

1
J'ai pris votre exemple de code sur mon serveur, cela fonctionne bien, puis j'ai créé de nouveaux exemples de plunker à partir de votre exemple plnkr.co/edit/V3kx7LQbTppaQ6V06uZp?p=preview il fonctionne également très bien. Aucun résultat d'erreur CSP.
Penseur

Ouais, ça marche très bien sur le plongeur que j'ai fait aussi. Je suis curieux de savoir comment cela fonctionne sur votre serveur, car après votre commentaire, j'ai triple vérifié et je ne peux pas le faire fonctionner sur mon serveur en direct, ou sur mon serveur local.
Veneseme Tyras

Réponses:



0

vous pouvez utiliser CSS au lieu de la balise iframe html car la balise iframe est supprimée en html


Jetez un coup d'œil à nouveau à Comment répondre . Comment résoudraient-ils exactement ce problème en utilisant CSS?
camille
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.