Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from access cro

Posted

技术标签:

【中文标题】Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from access cross-origin frame 同时在页面中列出 iframe【英文标题】:Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame while listing the iframes in page 【发布时间】:2018-12-12 06:34:38 【问题描述】:

我正在尝试在一个页面中列出所有 iframes 的名称,以便我可以通过 Selenium 访问它们。

问题是iframe的名字每次都在变化,所以我需要循环遍历它们。

我得到:

未捕获的 DOMException:阻止具有源“http://localhost:8080”的框架访问跨域框架。

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

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

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

【问题讨论】:

可能是Document.getElementsByTagName()? 您是在使用 javascript 与 selenium 还是其他语言? 我正在使用javascript + selenium 【参考方案1】:

此错误消息...

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

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


同源政策

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


跨域资源共享 (CORS)

Cross-Origin Resource Sharing (CORS) : 跨域资源共享 (CORS) 是一种使用附加 HTTP 标头 告诉 浏览器客户端AUT (正在测试的应用程序) 在一个来源(域)运行,有权访问来自不同来源的服务器的选定资源。当 Web 应用程序请求的资源与它自己的来源不同(domainprotocolport)时,它会发出跨域 HTTP 请求


来源示例

以下是与 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

出了什么问题

当您尝试循环访问 frames 时,您的脚本/程序尝试使用 JavaScript 访问具有不同来源的 &lt;iframe&gt;,如果您能实现它,这将是一个巨大的安全漏洞。如上所述,same-origin policy 浏览器会阻止脚本尝试访问具有不同来源的 &lt;iframe&gt;

如果 protocolport(如果指定了一个)和 host 对于两个页面都相同,则两个页面具有相同的来源网页。您有时会看到它被称为 "scheme/host/port tuple"(其中“元组”是由三个组件组成的集合,它们共同构成一个整体)。当您要访问时,可能 protocoldomainhostnameport 必须与您的同一域相同所需的框架。

解决方案

AUT 可能包含许多 frames / iframes,其中一些可能仅在某些 JavaScript 之后加载/ Ajax 已经完成,其中一些可能将 style 属性设置为 display:none;visiblity 隐藏。当然不需要与所有这些交互。因此,识别&lt;iframe&gt;属性 并相应地切换将是一种更好的方法。您可以通过以下方式切换到&lt;iframe&gt;

Frame Name Frame ID Frame Index WebElement

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

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


参考文献

一些参考资料:

在本次讨论中,您将找到对SecurityError: Blocked a frame with origin from accessing a cross-origin frame的详细分析

在本次讨论中,您将在Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?上找到不同的方法

在此讨论的A Better Approach to Switch Frames 部分,您将在How can I select a html element no matter what frame it is in in selenium? 上找到不同的方法

【讨论】:

【参考方案2】:

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

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

迭代此列表以获取属性。

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

【讨论】:

【参考方案3】:

肮脏的解决方案:

对于窗户:

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

Mac 版:

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

这样你就可以打开chrome,让它忽略网络安全。

【讨论】:

【参考方案4】:

您可以使用selenium 来获取这样的 iframe 标签:

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

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

iframe.getAttribute('name')

【讨论】:

以上是关于Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from access cro的主要内容,如果未能解决你的问题,请参考以下文章

出现错误 - Uncaught (in promise) DOMException: play() failed 因为用户没有先与文档交互

解决 Uncaught (in promise) DOMException: play() failed 因为用户没有先与文档交互

Uncaught (in promise) DOMException: Subscription failed - no active Service Worker

React Uncaught (in promise) DOMException: play() 请求被新的加载请求中断

EasyWasmPlayer播放视频报错Uncaught (in promise)DOMException

chrome 音乐 视频自动播放 忽略 Uncaught (in promise) DOMException: play() failed