Accéder à l'URL parent depuis l'iframe


187

D'accord, j'ai une page sur et sur cette page j'ai une iframe. Ce que je dois faire est sur la page iframe, découvrez quelle est l'URL de la page principale.

J'ai cherché et je sais que ce n'est pas possible si ma page iframe est sur un domaine différent, car il s'agit de scripts intersites. Mais partout où j'ai lu, il est dit que si la page iframe est sur le même domaine que la page parent, cela devrait fonctionner si je le fais par exemple:

parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href

... ou d'autres combos similaires, car il semble y avoir plusieurs façons d'obtenir les mêmes informations.

Quoi qu'il en soit, voici le problème. Mon iframe est sur le même domaine que la page principale, mais ce n'est pas sur le même domaine SUB. Donc par exemple j'ai

http: // www.monsite.com/pageA.html

et puis mon URL iframe est

http: // qa-www.mysite.com/pageB.html

Lorsque j'essaye de récupérer l'URL de pageB.html(la page iframe), j'obtiens toujours la même erreur d'accès refusé. Il semble donc que même les sous-domaines comptent comme des scripts intersites, est-ce correct ou est-ce que je fais quelque chose de mal?


Pouvez-vous simplement le transmettre dans l'URL du cadre? Tels que<iframe src="url?parent=parent-url"></iframe>
Biagio Arobba

Réponses:


21

Vous avez raison. Les sous-domaines sont toujours considérés comme des domaines séparés lors de l'utilisation des iframes. Il est possible de transmettre des messages en utilisant postMessage(...), mais d'autres API JS sont intentionnellement rendues inaccessibles.

Il est également toujours possible d'obtenir l'URL en fonction du contexte. Voir les autres réponses pour plus de détails.


1
Bon bien ça souffle juste. Mais au moins je sais que je ne deviens pas fou: (ah bien, plan B. merci. (Et désolé de ne pas mettre mes trucs dans les tags, merci pour la modification)
chronofwar

9
comment est-ce la réponse choisie? il existe de bien meilleures descriptions des solutions possibles ci-dessous.
Anoyz

1
D'accord! La réponse ci-dessous avec 80 votes est bien meilleure. Cette réponse est dans la spécification html.
Ligemer

4
vous POUVEZ interagir entre le 2. Mais vous devez ajouter le script suivant sur le parent et l'iframe: <script> document.domain = "mydomain.com"; </script>
George

2
"Voir les autres réponses pour plus de détails." hahah C'est comme: je n'ai aucune solution, je vois d'autres réponses, mais j'accepte aussi ma réponse.
Milad

371

Oui, l'accès à l'URL de la page parent n'est pas autorisé si l'iframe et la page principale ne sont pas dans le même (sous) domaine. Cependant, si vous avez juste besoin de l'URL de la page principale (c'est-à-dire l'URL du navigateur), vous pouvez essayer ceci:

var url = (window.location != window.parent.location)
            ? document.referrer
            : document.location.href;

Remarque:

window.parent.locationest autorisée; il évite l'erreur de sécurité dans l'OP, qui est provoquée par l'accès à la hrefpropriété: window.parent.location.hrefprovoque "Bloqué une trame d'origine ..."

document.referrerfait référence à «l'URI de la page qui a lié à cette page». Cela peut ne pas renvoyer le document contenant si une autre source est ce qui a déterminé l' iframeemplacement, par exemple:

  • Conteneur iframe @ Domain 1
  • Envoie l'iframe enfant au domaine 2
  • Mais dans l'iframe enfant ... Le domaine 2 redirige vers le domaine 3 (c'est-à-dire pour l'authentification, peut-être SAML), puis le domaine 3 renvoie vers le domaine 2 (c'est-à-dire via la soumission de formulaire (), une technique SAML standard)
  • Pour l'iframe enfant, le document.referrersera le domaine 3 , pas le domaine 1 contenant

document.locationfait référence à "un objet Location, qui contient des informations sur l'URL du document"; vraisemblablement le document actuel , c'est-à-dire l'iframe actuellement ouvert. Quand window.location === window.parent.location, alors l'iframe hrefest le même que le parent contenant href.


1
@jepser c'est parce que votre iframe est à l'intérieur de cette iframe. vous n'aurez jamais accès au cadre supérieur avec celui-ci au milieu. Les iframes inter-domaines imbriqués sont faux à bien des niveaux. mais vous pourrez peut-être contourner cela si vous placez document.domainle cadre supérieur et celui le plus intérieur. peut être.
gcb

2
Ou, un peu plus compact:var url = (parent !== window) ? document.referrer : document.location;
thekingoftruth

2
Veuillez noter que cela ne fonctionne pas si le conteneur est situé sur votre hôte local (ou plus généralement, si cette page n'est pas ouverte par un serveur web) ou appelé par file: //.
Guillaume Renoult

5
Il convient de noter que cela peut être vaincu avec l'en- Referer-Policytête.
Dan Atkinson

2
Cela ne semble pas fonctionner avec le navigateur Edge - le référent sera une chaîne vide. Stackoverflow.com/questions/24169219/…
Davide Orazio Montersino

52

Je viens de découvrir une solution de contournement pour ce problème qui est si simple, et pourtant je n'ai trouvé aucune discussion qui le mentionne. Cela nécessite le contrôle de la trame parent.

Dans votre iFrame, dites que vous voulez cette iframe: src = "http://www.example.com/mypage.php"

Eh bien, au lieu de HTML pour spécifier l'iframe, utilisez un javascript pour créer le HTML de votre iframe, obtenez l'url parent via javascript "au moment de la construction", et envoyez-la en tant que paramètre URL GET dans la chaîne de requête de votre cible src, comme alors:

<script type="text/javascript">
  url = parent.document.URL;
  document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>

Ensuite, trouvez-vous une fonction d'analyse d'url javascript qui analyse la chaîne d'url pour obtenir la variable d'url que vous recherchez, dans ce cas, c'est "url".

J'ai trouvé un excellent analyseur de chaînes d'URL ici: http://www.netlobo.com/url_query_string_javascript.html


Cette réponse combinée à stackoverflow.com/a/7739035/216084 fait le travail.

2
C'était une merveilleuse suggestion. Pour ceux qui écrivent le code iframe html parent, cela paierait la facture. Nous avons utilisé quelque chose de très similaire dans notre logiciel de pixel.
Ligemer

Je vous remercie!! Il s'agit d'une solution efficace qui respecte toujours les règles intersites.
theUtherSide

Mais réécrivez-vous toutes les URL du code HTML sur le serveur? Parce que sinon, lorsqu'un utilisateur clique sur un lien dans l'iFrame, il ne sera toujours pas accessible.
Roel

@Roel vous pouvez tous les écrire au moment du serveur (en substance, "coder en dur" cette réponse), ou cette réponse que vous pouvez faire en javascript, par exemple après le chargement de la page, elle injecte les iframes souhaitées.
rogerdpack

34

Si votre iframe provient d'un autre domaine (cross domain), vous devrez simplement utiliser ceci:

var currentUrl = document.referrer;

et - ici vous avez l'url principale!


Cela n'a pas fonctionné dans mon cas car je pense que l'iFrame lui-même a été généré dynamiquement ou a fait une autre supercherie. En tout cas, je n'ai pas obtenu la réponse que j'attendais.
Muskie

cela devrait fonctionner dans tous les navigateurs. Sauf dans les navigateurs plus récents si vous envoyez des paramètres Sandboxing, mais je doute que ce soit le cas. Cela fonctionne quel que soit le domaine croisé.
gcb

Si la page à l'intérieur de l'iframe s'est rechargée via javascript (par exemple window.location.reload(true)), cela ne fonctionne plus. Ensuite, le référent est l'URL de l'iframe lui-même.
mori

20

Pour les pages sur le même domaine et sous-domaine différent, vous pouvez définir la document.domainpropriété via javascript.

Le cadre parent et l'iframe doivent tous deux définir leur document.domain sur quelque chose qui est commun entre eux.

c'est-à www.foo.mydomain.com- dire et api.foo.mydomain.comchacun pourrait utiliser l'un foo.mydomain.comou l' autre ou juste mydomain.comet être compatible (non, vous ne pouvez pas les définir tous les deux com, pour des raisons de sécurité ...)

notez également que document.domain est une rue à sens unique. Pensez à exécuter les trois instructions suivantes dans l'ordre:

// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception

Les navigateurs modernes peuvent également utiliser window.postMessage pour parler des origines, mais cela ne fonctionnera pas dans IE6. https://developer.mozilla.org/en/DOM/window.postMessage


3
Veuillez accepter ceci comme réponse, maintenant que c'est à la fois possible et que cette réponse apparaît dans les recherches Google.
Metagrapher

17

La ligne suivante fonctionnera: document.location.ancestorOrigins[0]celle-ci renvoie le nom de domaine ancêtre.


Suite aux modifications apportées à Chrome, c'est désormais la bonne réponse pour de nombreux navigateurs.
Dan Atkinson

Pas l'URL complète cependant. Only the domain
TheMaster

document.location.ancestorOriginsrevient undefinedpour moi
Miguel Mota

En ce qui concerne la prise en charge des navigateurs, en particulier, depuis juillet 2020, ancestorOrigins n'est pas encore pris en charge dans Firefox en raison de problèmes de confidentialité. Demande de fonctionnalité et discussion sur Bugzilla : bugzilla.mozilla.org/show_bug.cgi?id=1085214 . Prise en charge du navigateur: caniuse.com/#search=ancestorOrigins
colin moock


2

J'ai eu des problèmes avec ça. Si vous utilisez un langage comme php lorsque votre page se charge pour la première fois dans l'iframe $_SERVER['HTTP_REFFERER']et définissez-la sur une variable de session.

De cette façon, lorsque la page se charge dans l'iframe, vous connaissez l'url parent complète et la chaîne de requête de la page qui l'a chargée. Avec la sécurité de plusieurs navigateurs, c'est un peu un casse-tête de compter sur window.parent si vous avez différents domaines.


2
var url = (window.location != window.parent.location) ? document.referrer: document.location;

J'ai trouvé que l'exemple ci-dessus suggéré précédemment fonctionnait lorsque le script était exécuté dans une iframe, mais il n'a pas récupéré l'url lorsque le script était exécuté en dehors d'une iframe, un léger ajustement était nécessaire:

var url = (window.location != window.parent.location) ? document.referrer: document.location.href;

2
Si vous êtes en dehors de l'iframe, vous exécutez le script sur le cadre parent, vous n'avez rien à vérifier.
Art3mix

1

Je n'ai pas pu faire fonctionner la solution précédente, mais j'ai découvert que si je définissais l'iframe scr avec par exemple, http:otherdomain.com/page.htm?from=thisdomain.com/thisfolderje pourrais, dans l'extrait d'iframe, thisdomain.com/thisfolderen utilisant le javascript suivant:

var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];

1

Le problème avec PHP $ _SERVER ['HTTP_REFFERER'] est qu'il donne l'URL de page entièrement qualifiée de la page qui vous a amené à la page parente. Ce n'est pas la même chose que la page parent elle-même. Pire, parfois il n'y a pas de http_referer, car la personne a tapé l'url de la page parent. Donc, si j'arrive à votre page parent depuis yahoo.com, alors yahoo.com devient le http_referer, pas votre page.


1

J'ai trouvé dans les cas où $_SERVER['HTTP_REFERER']ne fonctionne pas (je vous regarde, Safari), $_SERVER['REDIRECT_SCRIPT_URI']a été une sauvegarde utile.


0

Dans Chrome, il est possible d'utiliser location.ancestorOrigins Il retournera toutes les URL parentes


0

Je sais que le sien est super vieux, mais cela m'époustoufle, personne n'a recommandé de simplement passer des cookies d'un domaine à l'autre. Lorsque vous utilisez des sous-domaines, vous pouvez partager les cookies d'un domaine de base vers tous les sous-domaines simplement en définissant des cookies sur l'URL.basedomain.com

Ensuite, vous pouvez partager toutes les données dont vous avez besoin via les cookies.


-1

Cela a fonctionné pour moi pour accéder à l'url src iframe.

window.document.URL

-4

Obtenir toutes les fonctions Iframe parent et HTML

var parent = $(window.frameElement).parent();
        //alert(parent+"TESTING");
        var parentElement=window.frameElement.parentElement.parentElement.parentElement.parentElement;
        var Ifram=parentElement.children;      
        var GetUframClass=Ifram[9].ownerDocument.activeElement.className;
        var Decision_URLLl=parentElement.ownerDocument.activeElement.contentDocument.URL;

Je suppose que vous ne pouvez pas étendre cette réponse à ceux d'entre nous qui n'utilisent pas jQuery (un nombre croissant, je dois le signaler, car jQuery est devenu de plus en plus inutile au cours des dernières années). À tout le moins, je suggère de préciser que cette réponse dépend de jQuery et que l'OP n'a pas du tout mentionné jQuery.
Carnix
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.