SecurityError: Bloqué un cadre avec l'origine d'accéder à un cadre de cross-origin
je charge un <iframe>
dans ma page HTML et j'essaie d'accéder aux éléments qu'il contient en utilisant Javascript, mais quand j'essaie d'exécuter mon code, j'obtiens l'erreur suivante:
SecurityError: Blocked a frame with origin "http://www.<domain>.com" from accessing a cross-origin frame.
pouvez-vous s'il vous plaît m'aider à trouver une solution pour que je puisse accéder aux éléments dans le cadre?
j'utilise ce code pour tester, mais en vain:
$(document).ready(function() {
var iframeWindow = document.getElementById("my-iframe-id").contentWindow;
iframeWindow.addEventListener("load", function() {
var doc = iframe.contentDocument || iframe.contentWindow.document;
var target = doc.getElementById("my-target-id");
target.innerHTML = "Found it!";
});
});
6 réponses
Politique de même origine
à ne pas confondre avec CORS !
vous can't accédez à un <iframe>
avec une origine différente en utilisant JavaScript, ce serait un énorme défaut de sécurité si vous pouviez le faire. Pour le 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 une des parties suivantes de l'adresse n'est pas conservée:
<protocol>://<hostname>:<port>/path/to/page.html
protocole , nom d'hôte et port doit être le même de votre domaine, si vous voulez accéder à un cadre.
exemples
voici ce qui se passerait en essayant d'accéder aux URLs 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.html -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different hostname & protocol
solution de contournement
bien que la Politique de même origine bloque les scripts d'accéder au contenu des sites avec une origine différente, si vous possédez les deux pages, vous pouvez contourner ce problème en utilisant window.postMessage
et son relatif message
événement pour envoyer des messages entre les deux pages, comme ceci:
-
dans votre page principale:
var frame = document.getElementById('your-frame-id'); frame.contentWindow.postMessage(/*any variable or object here*/, '*');
-
Dans votre
<iframe>
(figurant dans la page principale):window.addEventListener('message', function(event) { // IMPORTANT: Check the origin of the data! if (~event.origin.indexOf('http://yoursite.com')) { // The data has been sent from your site // The data sent with postMessage is stored in event.data console.log(event.data); } else { // The data hasn't been sent from your site! // Be careful! Do not use it. return; } });
cette méthode peut être appliquée dans les deux directions , en créant un auditeur dans la page principale aussi, et en recevant des réponses à partir du cadre. La même logique peut également être implémentée dans les pop-ups et essentiellement toute nouvelle fenêtre générée par la page principale (par exemple en utilisant window.open()
) ainsi, sans aucune différence.
Désactivation de la même origine " politique votre navigateur
il y a déjà quelques bonnes réponses à ce sujet (je viens de les trouver googling), donc, pour les navigateurs où cela est possible, je vais lier la réponse relative. Toutefois, veuillez vous rappeler que désactiver la Politique de même origine (ou la LCS) ne touchera que votre navigateur . En outre, l'exécution d'un navigateur avec des paramètres de sécurité de même origine subventions tout l'accès au site web à des ressources de cross-origine, si il est très dangereux et devrait être fait à des fins de développement seulement .
- Google Chrome
- Mozilla Firefox
- Apple Safari: pas possible, seulement CORS .
- Opéra: impossible.
- Microsoft Edge: pas possible.
- Microsoft Internet Explorer: pas possible, seulement de la SCRO .
complétant la réponse de Marco Bonelli: la meilleure façon actuelle d'interagir entre les cadres/iframes est d'utiliser window.postMessage
, pris en charge par tous les navigateurs
Vérifier le serveur web du domaine pour http://www.<domain>.com
configuration pour X-Frame-Options
C'est un dispositif de sécurité conçu pour empêcher le détournement de clics attaques,
comment fonctionne clickJacking?
- la page du mal ressemble exactement à la page de la victime.
- puis il a trompé les utilisateurs pour entrer leur nom d'utilisateur et mot de passe.
techniquement le mal a un iframe
avec la source à la victime de la page.
<html>
<iframe src='victim_domain.com'/>
<input id="username" type="text" style="display: none;/>
<input id="password" type="text" style="display: none;/>
<script>
//some JS code that click jacking the user username and input from inside the iframe...
<script/>
<html>
Comment fonctionne la caractéristique de sécurité
si vous voulez empêcher la requête du serveur web d'être rendue dans un iframe
ajouter le X-frame-options
X-Frame-Options DENY
les options sont:
- SAMEORIGIN //autoriser uniquement pour mon propre nom de domaine, de rendre mon code HTML à l'intérieur d'une iframe.
- DENY //ne permettent pas de mon code HTML pour être affiché à l'intérieur de toute iframe
- "PERMETTENT DE https://example.com/ " //permet de domaine spécifique pour rendre mon code HTML à l'intérieur d'une iframe
C'est l'exemple de configuration IIS:
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
la solution à la question
si le serveur web active la fonctionnalité de sécurité, il peut causer une erreur de sécurité côté client comme il le devrait.
pour moi, je voulais mettre en place une poignée de main bidirectionnelle, ce qui signifie:
- la fenêtre parent se chargera plus rapidement que l'iframe
- l'iframe devrait parler à la fenêtre parent dès que son prêt
- le parent est prêt à recevoir le message iframe et rejouer
ce code est utilisé pour définir l'étiquette blanche dans l'iframe en utilisant [css custom property]
code:
iframe
$(function() {
window.onload = function() {
// create listener
function receiveMessage(e) {
document.documentElement.style.setProperty('--header_bg', e.data.wl.header_bg);
document.documentElement.style.setProperty('--header_text', e.data.wl.header_text);
document.documentElement.style.setProperty('--button_bg', e.data.wl.button_bg);
//alert(e.data.data.header_bg);
}
window.addEventListener('message', receiveMessage);
// call parent
parent.postMessage("GetWhiteLabel","*");
}
});
parent
$(function() {
// create listener
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
// replay to child (iframe)
document.getElementById('wrapper-iframe').contentWindow.postMessage(
{
event_id: 'white_label_message',
wl: {
header_bg: $('#Header').css('background-color'),
header_text: $('#Header .HoverMenu a').css('color'),
button_bg: $('#Header .HoverMenu a').css('background-color')
}
},
'*'
);
}, false);
});
naturellement, vous pouvez limiter les origines et le texte, c'est facile à travailler-avec le code
j'ai trouvé cet examlpe utile.:
[ Cross-Domain Messaging With postMessage]
mon application s'écrasait avec un SecurityError
placé dans un iframe
.
Le problème était que le .animate({scrollTop: top}, 0)
de jQuery était appliqué directement sur le window
.
la suppression de ce LOC a réglé le problème pour nous.
ouvrir le menu Démarrer
Tapez windows+R ou ouvrez " Run
Exécutez la commande suivante.
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security