Javascript 错误:访问属性“文档”的权限被拒绝

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36333978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:56:42  来源:igfitidea点击:

Error: Permission denied to access property "document"

javascripthtmliframexssaccess-control

提问by sbrm1

I have a HTML Document which contains an iframe. Whenever I try to access or modify this iframewith JS I get Error: Permission denied to access property "document".

我有一个 HTML 文档,其中包含iframe. 每当我尝试iframe使用 JS访问或修改它时,我都会得到Error: Permission denied to access property "document".

I am using frame.contentWindow.document.body.innerHTMLor frame.contentWindow.document.body.onloador similar such attributes to access or modify the iframe. (In the given code the iframeis referred to as frame.)

我正在使用frame.contentWindow.document.body.innerHTMLframe.contentWindow.document.body.onload类似这样的属性来访问或修改iframe. (在给定的代码中iframe被称为frame。)

For the web-app I am developing, access to these attributes are necessary and I can't do without these (or similar alternatives).

对于我正在开发的网络应用程序,访问这些属性是必要的,我不能没有这些(或类似的替代品)。

采纳答案by Gihan Gamage

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>

回答by sbrm1

Accessing and then modifying webpages in iframes of other websites is known as Cross-site scriptingor XSSand 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 iframein the same domain and subdomain, and making sure that the documents are loaded using the same protocol.

通过iframe在同一域和子域中托管父文档和文档,并确保使用相同的协议加载文档,可以防止此错误。

Examples of Incompatible Pages:

不兼容页面示例:

  1. http://www.example.org& http://www.example2.com
  2. http://abc.example.org& http://xyz.example.com
  3. http://www.example.org& https://www.example.com
  1. http://www.example.org& http://www.example2.com
  2. http://abc.example.org& http://xyz.example.com
  3. http://www.example.org& https://www.example.com


Cross-Origin Resource Sharingis a solution to this problem.

跨域资源共享就是解决这个问题的方法。

For Example:
If http://www.example.comwould like to share http://www.example.com/hellowith http://www.example.org, a header can be sent with the document which looks like the following:

例如:
如果http://www.example.com希望共享http://www.example.com/hellohttp://www.example.org,报头可以与如下所示的文件被发送:

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 发送它,只需将它放在一个<META HTTP-EQUIV="...">标签中,如下所示:

<head>
    ...
    <META HTTP-EQUIV="Access-Control-Allow-Origin" CONTENT="http://www.example.org">
    ...
</head>

回答by joyBlanks

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.

您必须创建另一对才能相互通信。