Javascript 未捕获的 DOMException:在列出页面中的 iframe 时阻止了源为“http://localhost:8080”的框架访问跨源框架

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51163151/
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 04:46:59  来源:igfitidea点击:

Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame while listing the iframes in page

javascriptseleniumiframesame-origin-policy

提问by TwoShorts

I am trying to list the names of all the iframes in a page, so I can access them through Selenium.

我试图列出iframe页面中所有s的名称,以便我可以通过 Selenium 访问它们。

The problem is that the name of the iframechanges each time, so I need to loop through all of them.

问题是iframe每次更改的名称,所以我需要遍历所有这些。

I am getting:

我正进入(状态:

Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.

未捕获的 DOMException:阻止了一个带有“ http://localhost:8080”的框架访问跨源框架。

error when I try to loop over them using:

当我尝试使用以下方法循环它们时出错:

for (var f = 0; f < window.frames.length; f++) {
    console.log(window.frames[f].name)
}

Is there a way to get the name of the iframein a different way?

有没有办法以iframe不同的方式获得名称?

回答by DebanjanB

This error message...

这个错误信息...

Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.

...implies that the WebDriverinstance blockedfrom accessing a cross-origin frame.

...暗示WebDriver实例被阻止访问跨域框架。



Same-origin policy

同源策略

Same-origin policy: Same-origin policy restricts how a document or script loaded from one origin can interact with a resource from another origin. It is a critical security mechanismfor isolating potentially malicious documents.

同源策略:同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源交互。它是隔离潜在恶意文档的关键安全机制



Cross-Origin Resource Sharing (CORS)

跨域资源共享 (CORS)

Cross-Origin Resource Sharing (CORS): Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headersto tell a Browser Clientto let the AUT (Application under Test)running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP requestwhen it requests a resource that has a different origin (domain, protocol, and port) than its own origin.

Cross-Origin Resource Sharing (CORS):Cross-Origin Resource Sharing (CORS) 是一种机制,它使用额外的HTTP 标头告诉浏览器客户端让在一个源(域)运行的AUT(被测应用程序)有权访问从不同来源的服务器中选择的资源。一个Web应用程序进行跨域HTTP请求时,它要求具有不同的原点(资源domainprotocolport)比它自己的起源。



Example of an origin

起源的例子

Here is an example of origin comparisons to the URL http://store.company.com/dir/page.html

这是与 URL 的来源比较的示例 http://store.company.com/dir/page.html

URL                                                  Outcome    Reason
http://store.company.com/dir2/other.html             Success
http://store.company.com/dir/inner/another.html      Success
https://store.company.com/secure.html                Failure    Different protocol
http://store.company.com:81/dir/etc.html             Failure    Different port
http://news.company.com/dir/other.html               Failure    Different host


What went wrong

什么地方出了错

When you tried to loop through framesyour script/program tried to access an <iframe>with different origin using JavaScript which would been a huge security flawif you would have achieved it. As mentioned above the same-origin policybrowsers block scripts trying to access a <iframe>with a different origin.

当您尝试遍历frames脚本/程序时,尝试<iframe>使用 JavaScript访问具有不同来源的内容,如果您能够实现它,这将是一个巨大的安全漏洞。如上所述,同源策略浏览器会阻止尝试访问<iframe>具有不同来源的a 的脚本。

Two pages have the same origin if the protocol, port(if one is specified), and hostare the same for both the webpages. You'll see this referred to as the "scheme/host/port tuple"at times (where a "tuple" is a set of three components that together comprise a whole). Perhaps the protocol, domain, hostnameand portmust be the same of your same domain when you want to access the desired frame.

如果两个网页的协议端口(如果指定了一个)和主机相同,则两个网页具有相同的来源。您会看到这被称为"scheme/host/port tuple"时间(其中“元组”是由三个组件组成的集合,它们共同构成一个整体)。当您想要访问所需的帧时,可能协议主机名端口必须与您的域相同。

Solution

解决方案

The AUTmay contain numerous frames/ iframesand some of them may be loaded only after certain JavaScript/ Ajaxhave completed where as some of them may be having styleattribute set as display:none;or visiblityas hidden. Of-course won't require to interact with all of them. So it will be a better approach to identify the attributesof the <iframe>and switch accordingly. You can switch to an <iframe>through:

所述AUT可能包含众多/内部框架和其中一些可能只有在某些加载的JavaScript/ Ajax的已完成,其中作为它们中的一些可以具有样式属性集为显示:无; 可见性hidden。当然,不需要与所有人互动。因此,这将是一个更好的方式来确定的属性<iframe>,并相应地进行切换。您可以切换到<iframe>直通:

  • Frame Name
  • Frame ID
  • Frame Index
  • WebElement
  • Frame Name
  • Frame ID
  • Frame Index
  • WebElement

As per best practiceswhen you intent to switch to a frame induce WebDriverWaitfor frameToBeAvailableAndSwitchToItas per the references below.

根据最佳实践,当您打算切换到框架时,请按照以下参考为frameToBeAvailableAndSwitchToIt引入WebDriverWait

Here you can find a relevant discussion on Uncaught DOMException

在这里您可以找到有关Uncaught DOMException的相关讨论



References

参考

Some references:

一些参考:

回答by Angia

Dirty solution:

脏的解决办法:

for windows:

对于窗户:

chrome.exe --user-data-dir="" --disable-web-security

for mac:

对于 Mac:

open -a Google\ Chrome --args --disable-web-security --user-data-dir=""

In this way you open the chrome and let it ignore the web security.

通过这种方式,您可以打开 chrome 并让它忽略网络安全。

回答by PixelEinstein

You can use seleniumto get iframe tags like this:

您可以使用以下selenium方式获取 iframe 标签:

var iframeElems = driver.findElements(webdriver.By.xpath("//iframe"));

Then loop on those elements and get the nameattribute:

然后在这些元素上循环并获取name属性:

iframe.getAttribute('name')

回答by cruisepandey

You can try something like this : (Not sure about JavaScript)

你可以试试这样的:(不确定 JavaScript)

var iframeElems = driver.findElements(webdriver.By.tagName("iframe"));

iterate this list to get the attribute.

迭代此列表以获取属性。

for (var f = 0; f < iframeElems.length; f++) {
    console.log(iframeElems.getAttribute("attribute name"))
}