I have a HTML Document which contains an iframe
. Whenever I try to access or modify this iframe
with JS I get Error: Permission denied to access property "document"
.
我有一个包含iframe的HTML文档。每当我尝试使用JS访问或修改此iframe时,我都会收到Error:Permission denied to access property“document”。
I am using frame.contentWindow.document.body.innerHTML
or frame.contentWindow.document.body.onload
or similar such attributes to access or modify the iframe
. (In the given code the iframe
is referred to as frame
.)
我正在使用frame.contentWindow.document.body.innerHTML或frame.contentWindow.document.body.onload或类似的此类属性来访问或修改iframe。 (在给定代码中,iframe称为帧。)
For the web-app I am developing, access to these attributes are necessary and I can't do without these (or similar alternatives).
对于我正在开发的web-app,访问这些属性是必要的,我不能没有这些(或类似的替代品)。
3 个解决方案
#1
14
Accessing and then modifying webpages in iframe
s of other websites is known as Cross-site scripting or XSS and it is a technique used by malicious hackers to prey on unsuspecting victims.
访问并修改其他网站的iframe中的网页称为跨站点脚本或XSS,它是恶意黑客用来捕获毫无戒心的受害者的技术。
A policy by the name of "Same-Origin Policy" is implemented by browser makers to prevent such behaviour and arbitrary execution of JS code.
浏览器制造商实施了名为“同源策略”的策略,以防止此类行为和JS代码的任意执行。
This error can be prevented by hosting the parent document and the document in the iframe
in the same domain and subdomain, and making sure that the documents are loaded using the same protocol.
通过将父文档和文档托管在同一域和子域中的iframe中,并确保使用相同的协议加载文档,可以防止此错误。
Examples of Incompatible Pages:
不兼容页面的示例:
-
http://www.example.org
&http://www.example2.com
-
http://abc.example.org
&http://xyz.example.com
-
http://www.example.org
&https://www.example.com
http://www.example.org和http://www.example2.com
http://abc.example.org&http://xyz.example.com
http://www.example.org&https://www.example.com
Cross-Origin Resource Sharing is a solution to this problem.
跨源资源共享是此问题的解决方案。
For Example:
If http://www.example.com
would like to share http://www.example.com/hello
with http://www.example.org
, a header can be sent with the document which looks like the following:
例如:如果http://www.example.com想与http://www.example.org共享http://www.example.com/hello,则可以使用看起来像的文档发送标题下列:
Access-Control-Allow-Origin: http://www.example.org
To send it with HTML just put it in a <META HTTP-EQUIV="...">
tag, like this:
要使用HTML发送它只需将其放在 标记中,如下所示:
<head>
...
<META HTTP-EQUIV="Access-Control-Allow-Origin" CONTENT="http://www.example.org">
...
</head>
#2
5
You can use postMessage
您可以使用postMessage
Window 1 - receiving
窗口1 - 接收
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;
// ...
}
Window - 2 Transmitting
窗口 - 2发射
var popup = window.open(...popup details...);
popup.postMessage(
"The user is 'bob' and the password is 'secret'",
"https://secure.example.net"
);
You have to create another pair to intercommunicate.
您必须创建另一对以进行相互通信。
#3
2
You can still bypass this issue with the help of YQL even though you don't have access to the header part of the receiving window. With the Postmessage method also you need to edit the recipient window script. But using this method you can load any iframe without touching their scripts. Check this out!
即使您无法访问接收窗口的标题部分,仍可以借助YQL绕过此问题。使用Postmessage方法,您还需要编辑收件人窗口脚本。但是使用此方法,您可以加载任何iframe而无需触及其脚本。看一下这个!
<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>
#1
14
Accessing and then modifying webpages in iframe
s of other websites is known as Cross-site scripting or XSS and it is a technique used by malicious hackers to prey on unsuspecting victims.
访问并修改其他网站的iframe中的网页称为跨站点脚本或XSS,它是恶意黑客用来捕获毫无戒心的受害者的技术。
A policy by the name of "Same-Origin Policy" is implemented by browser makers to prevent such behaviour and arbitrary execution of JS code.
浏览器制造商实施了名为“同源策略”的策略,以防止此类行为和JS代码的任意执行。
This error can be prevented by hosting the parent document and the document in the iframe
in the same domain and subdomain, and making sure that the documents are loaded using the same protocol.
通过将父文档和文档托管在同一域和子域中的iframe中,并确保使用相同的协议加载文档,可以防止此错误。
Examples of Incompatible Pages:
不兼容页面的示例:
-
http://www.example.org
&http://www.example2.com
-
http://abc.example.org
&http://xyz.example.com
-
http://www.example.org
&https://www.example.com
http://www.example.org和http://www.example2.com
http://abc.example.org&http://xyz.example.com
http://www.example.org&https://www.example.com
Cross-Origin Resource Sharing is a solution to this problem.
跨源资源共享是此问题的解决方案。
For Example:
If http://www.example.com
would like to share http://www.example.com/hello
with http://www.example.org
, a header can be sent with the document which looks like the following:
例如:如果http://www.example.com想与http://www.example.org共享http://www.example.com/hello,则可以使用看起来像的文档发送标题下列:
Access-Control-Allow-Origin: http://www.example.org
To send it with HTML just put it in a <META HTTP-EQUIV="...">
tag, like this:
要使用HTML发送它只需将其放在 标记中,如下所示:
<head>
...
<META HTTP-EQUIV="Access-Control-Allow-Origin" CONTENT="http://www.example.org">
...
</head>
#2
5
You can use postMessage
您可以使用postMessage
Window 1 - receiving
窗口1 - 接收
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;
// ...
}
Window - 2 Transmitting
窗口 - 2发射
var popup = window.open(...popup details...);
popup.postMessage(
"The user is 'bob' and the password is 'secret'",
"https://secure.example.net"
);
You have to create another pair to intercommunicate.
您必须创建另一对以进行相互通信。
#3
2
You can still bypass this issue with the help of YQL even though you don't have access to the header part of the receiving window. With the Postmessage method also you need to edit the recipient window script. But using this method you can load any iframe without touching their scripts. Check this out!
即使您无法访问接收窗口的标题部分,仍可以借助YQL绕过此问题。使用Postmessage方法,您还需要编辑收件人窗口脚本。但是使用此方法,您可以加载任何iframe而无需触及其脚本。看一下这个!
<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>