Politique de même origine
Vous ne pouvez pas accéder à une <iframe>
origine différente en utilisant JavaScript, ce serait une énorme faille de sécurité si vous pouviez le faire. Pour la politique de même origine, les navigateurs bloquent les scripts essayant d'accéder à un cadre avec une origine différente .
L'origine est considérée comme différente si au moins l'une des parties suivantes de l'adresse n'est pas conservée:
<protocol>://<hostname>:<port>/...
Le protocole , le nom d'hôte et le port doivent être identiques à ceux de votre domaine, si vous souhaitez accéder à une trame.
REMARQUE: Internet Explorer est connu pour ne pas suivre strictement cette règle, voir ici pour plus de détails.
Exemples
Voici ce qui se passerait en essayant d'accéder aux URL suivantes à partir de http://www.example.com/home/index.html
URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html:80 -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different protocol, port & hostname
solution de contournement
Même si la stratégie de même origine empêche les scripts d'accéder au contenu des sites d'origine différente, si vous possédez les deux pages, vous pouvez contourner ce problème en utilisant window.postMessage
et son message
événement relatif pour envoyer des messages entre les deux pages, comme ceci:
Dans votre page principale:
let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
Le deuxième argument de postMessage()
peut être '*'
d'indiquer aucune préférence quant à l'origine de la destination. Une origine cible doit toujours être fournie lorsque cela est possible, pour éviter de divulguer les données que vous envoyez à tout autre site.
Dans votre <iframe>
(contenu dans la page principale):
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://your-first-site.com')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
Cette méthode peut être appliquée dans les deux sens , en créant également un écouteur dans la page principale et en recevant les réponses du cadre. La même logique peut également être implémentée dans les fenêtres contextuelles et, fondamentalement, dans toute nouvelle fenêtre générée par la page principale (par exemple en utilisant window.open()
), sans aucune différence.
Désactiver la politique de même origine dans votre navigateur
Il y a déjà de bonnes réponses à ce sujet (je viens de les trouver sur Google), donc, pour les navigateurs où cela est possible, je lierai la réponse relative. Cependant, n'oubliez pas que la désactivation de la politique de même origine n'affectera que votre navigateur . En outre, l'exécution d'un navigateur avec des paramètres de sécurité de même origine désactivés permet à tout site Web d'accéder à des ressources d'origine croisée, donc c'est très dangereux et ne devrait JAMAIS être fait si vous ne savez pas exactement ce que vous faites (par exemple à des fins de développement) .
Access-Control-Allow-Origin
ne s'applique pas aux iFrames, seulement aux XHR, aux polices, à WebGL etcanvas.drawImage
. Je crois quepostMessage
c'est la seule option.iframe.src
, et si le site est différent du nom d'hôte de votre domaine, vous ne pouvez pas accéder à ce cadre.~
renvoie le complément à 2 du nombre,n
devient ainsi-n-1
, ce qui signifie que seul-1
deviendra0
(ce qui est interprété commefalse
), et toute autre valeur passera le test. IE0 = -(-1)-1
, non-(-1+1)
.location.ancestorOrigins[0]
est l'emplacement du cadre parent. Si votre cadre s'exécute dans un autre site et que vous vérifiez en utilisantevent.origin.indexOf(location.ancestorOrigins[0])
vous vérifiez si l'origine de l'événement contient l'adresse du cadre du parent, qui sera toujourstrue
, par conséquent, vous autorisez tout parent avec n'importe quelle origine à accéder à votre cadre, et cela n'est évidemment pas quelque chose que vous voulez faire. De plus,document.referrer
c'est aussi une mauvaise pratique, comme je l'ai déjà expliqué dans les commentaires ci-dessus.Compléter la réponse de Marco Bonelli: la meilleure façon actuelle d'interagir entre les cadres / iframes est utilisée
window.postMessage
, prise en charge par tous les navigateursla source
window.postMessage
fonctionne ne ferait que reproduire la réponse acceptée à laquelle je fais déjà référence. De plus, la valeur essentielle que ma réponse ajoute est exactement celle de référencer la documentation externe.Vérifiez la
http://www.<domain>.com
configuration du serveur Web du domaine carX-Frame-Options
il s'agit d'une fonction de sécurité conçue pour empêcher les attaques clickJacking,Comment fonctionne clickJacking?
Techniquement, le mal a une
iframe
source sur la page de la victime.Fonctionnement de la fonction de sécurité
Si vous souhaitez empêcher le rendu de la demande du serveur Web dans un
iframe
add the x-frame-optionsLes options sont les suivantes:
Voici un exemple de configuration IIS:
La solution à la question
Si le serveur Web a activé la fonction de sécurité, cela peut provoquer une erreur de sécurité côté client comme il se doit.
la source
Pour moi, je voulais implémenter une poignée de main à 2 voies, ce qui signifie:
- la fenêtre parent se chargera plus rapidement que l'iframe
- l'iframe devrait parler à la fenêtre parent dès qu'elle est prête
- le parent est prêt à recevoir le message iframe et à rejouer
ce code est utilisé pour définir une étiquette blanche dans l'iframe à l'aide du code [propriété personnalisée CSS]
:
iframe
parent
naturellement, vous pouvez limiter les origines et le texte, c'est du code facile à travailler,
j'ai trouvé cet examen utile:
[Messagerie interdomaines avec postMessage]
la source
Je voudrais ajouter une configuration spécifique à Java Spring qui peut affecter cela.
Dans le site Web ou l'application Gateway, il existe un paramètre contentSecurityPolicy
au printemps, vous pouvez trouver l'implémentation de la sous-classe WebSecurityConfigurerAdapter
...
Le navigateur sera bloqué si vous n'avez pas défini de contenu externe sécurisé ici.
la source
Si vous contrôlez le contenu de l'iframe - c'est-à-dire s'il est simplement chargé dans une configuration d'origine croisée comme sur Amazon Mechanical Turk - vous pouvez contourner ce problème avec l'
<body onload='my_func(my_arg)'>
attribut pour le html interne.Par exemple, pour le html interne, utilisez le
this
paramètre html (oui -this
est défini et fait référence à la fenêtre parent de l'élément de corps interne):<body onload='changeForm(this)'>
Dans le html intérieur:
la source
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security
la source