Je charge un <iframe>
dans ma page HTML et j'essaie d'accéder aux éléments qu'il contient à l'aide de Javascript, mais lorsque j'essaie d'exécuter mon code, le message d'erreur suivant s'affiche:
SecurityError: Blocked a frame with Origin "http://www.<domain>.com" from accessing a cross-Origin frame.
Pouvez-vous m'aider à trouver une solution pour pouvoir accéder aux éléments du 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!";
});
});
Ne pas confondre avec CORS !
Vous ne pouvez pas accéder à un _<iframe>
_ avec une origine différente à l'aide de JavaScript, ce serait une faille de sécurité énorme si vous pouviez le faire. Pour les règle de même origine, les navigateurs bloquent les scripts qui tentent d'accéder à un cadre ayant une origine différente .
L'origine est considérée 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 identique à votre domaine si vous souhaitez accéder à un cadre.
Voici ce qui arriverait 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.html -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different hostname & protocol
_
Même si la politique de même origine empêche les scripts d'accéder au contenu de sites ayant une origine différente , si vous possédez les deux pages, vous pouvez contourner ce problème à l'aide de window.postMessage
et son événement relatif message
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*/, '*');
_
Dans votre _<iframe>
_ (contenu 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 également un écouteur sur la page principale et en recevant des réponses de la base. 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()
) également, sans aucune différence.
Il existe déjà de bonnes réponses à ce sujet (je viens de les trouver sur Google), aussi, pour les navigateurs où cela est possible, je vais relier la réponse relative. Cependant, rappelez-vous que la désactivation de la politique de même origine (ou du CORS) n’affectera que votre navigateur . En outre, l’exécution d’un navigateur avec des paramètres de sécurité identiques à l’origine désactivée accorde à tout accès des sites Web aux ressources croisées, de sorte que est très dangereux et devrait être supprimé. fait à des fins de développement uniquement .
Complément de la réponse de Marco Bonelli: le meilleur moyen d'interagir actuellement entre les cadres/iframes est d'utiliser window.postMessage
, pris en charge par tous les navigateurs
Vérifiez le serveur Web du domaine pour http://www.<domain>.com
configuration pour X-Frame-Options
Il s'agit d'une fonctionnalité de sécurité conçue pour empêcher les attaques de clickJacking,
Techniquement, la perversité a un iframe
avec le source de la page de victime.
<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>
Si vous souhaitez empêcher le rendu de la requête du serveur Web dans un iframe
ajoutez le x-frame-options
X-Frame-Options DENY
Les options sont:
Ceci est IIS exemple de configuration:
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
Si le serveur Web a activé la fonctionnalité de sécurité, cela peut provoquer une erreur SecurityError côté client comme il se doit.
Pour moi, je voulais mettre en place une poignée de main à double sens, ce qui signifie:
- la fenêtre parente se chargera plus rapidement que l'iframe
- l’iframe devrait parler à la fenêtre parente dès que sa fenêtre est prête.
- le parent est prêt à recevoir le message iframe et à le rejouer
ce code est utilisé pour définir une étiquette blanche dans l'iframe à l'aide de [propriété personnalisée CSS]
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, il est facile de travailler avec du code
J'ai trouvé cet exemple utile:
[[Messagerie inter-domaines avec postMessage]