J'ai un document HTML qui contient un iframe
. Chaque fois que j'essaie d'accéder ou de modifier ce iframe
avec JS, je reçois Error: Permission denied to access property "document"
.
J'utilise frame.contentWindow.document.body.innerHTML
ou frame.contentWindow.document.body.onload
ou des attributs similaires pour accéder ou modifier le iframe
. (Dans le code donné, iframe
est appelé frame
.)
Pour l'application Web que je développe, l'accès à ces attributs est nécessaire et je ne peux pas me passer de ceux-ci (ou d'alternatives similaires).
Vous pouvez toujours contourner ce problème à l'aide de YQL même si vous n'avez pas accès à la partie en-tête de la fenêtre de réception. Avec la méthode Postmessage, vous devez également modifier le script de la fenêtre du destinataire. Mais en utilisant cette méthode, vous pouvez charger n’importe quel iframe sans toucher à leurs scripts. Regarde ça!
<html>
<iframe src="https://google.com/" width="500" height="300"></iframe>
<script>
var iframe = document.getElementsByTagName('iframe')[0];
var url = iframe.src;
var getData = function (data) {
if (data && data.query && data.query.results && data.query.results.resources && data.query.results.resources.content && data.query.results.resources.status == 200) loadHTML(data.query.results.resources.content);
else if (data && data.error && data.error.description) loadHTML(data.error.description);
else loadHTML('Error: Cannot load ' + url);
};
var loadURL = function (src) {
url = src;
var script = document.createElement('script');
script.src = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20data.headers%20where%20url%3D%22' + encodeURIComponent(url) + '%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=getData';
document.body.appendChild(script);
};
var loadHTML = function (html) {
iframe.src = 'about:blank';
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html.replace(/<head>/i, '<head><base href="' + url + '"><scr' + 'ipt>document.addEventListener("click", function(e) { if(e.target && e.target.nodeName == "A") { e.preventDefault(); parent.loadURL(e.target.href); } });</scr' + 'ipt>'));
iframe.contentWindow.document.close();
}
loadURL(iframe.src);
</script>
</html>
Accéder à, puis modifier des pages Web dans iframe
s d’autres sites Web est appelé script intersite ou XSS et c'est une technique utilisée par des pirates informatiques malveillants pour s'en prendre à des victimes sans méfiance.
Une stratégie portant le nom de "Stratégie d'origine identique" est mise en œuvre par les fabricants de navigateur pour empêcher un tel comportement et l'exécution arbitraire de code JS.
Cette erreur peut être évitée en hébergeant le document parent et le document dans iframe
dans le même domaine et sous-domaine et en s'assurant que les documents sont chargés à l'aide du même protocole.
Exemples de pages incompatibles:
http://www.example.org
& http://www.example2.com
http://abc.example.org
& http://xyz.example.com
http://www.example.org
& https://www.example.com
Partage de ressources d'origine croisée est une solution à ce problème.
Par exemple:
Si http://www.example.com
aimerait partager http://www.example.com/hello
avec http://www.example.org
, un en-tête peut être envoyé avec le document qui se présente comme suit:
Access-Control-Allow-Origin: http://www.example.org
Pour l'envoyer avec HTML, il suffit de le mettre dans un <META HTTP-EQUIV="...">
tag, comme ceci:
<head>
...
<META HTTP-EQUIV="Access-Control-Allow-Origin" CONTENT="http://www.example.org">
...
</head>
Vous pouvez utiliser postMessage
Fenêtre 1 - réception
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
var Origin = event.Origin || event.originalEvent.Origin;
// For Chrome, the Origin property is in the event.originalEvent object.
if (Origin !== "http://example.org:8080")
return;
// ...
}
Fenêtre - 2 Transmission
var popup = window.open(...popup details...);
popup.postMessage(
"The user is 'bob' and the password is 'secret'",
"https://secure.example.net"
);
Vous devez créer une autre paire pour communiquer.