未捕获的 DOMException:在页面中列出 iframe 时阻止了来源为 "http://localhost:8080" 的框架访问跨域框架
Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame while listing the iframes in page
我试图列出页面中所有 iframe
的名称,以便我可以通过 Selenium 访问它们。
问题是 iframe
的名字每次都变了,所以我需要遍历所有的名字。
我得到:
Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
当我尝试使用以下方法遍历它们时出错:
for (var f = 0; f < window.frames.length; f++) {
console.log(window.frames[f].name)
}
有没有办法以不同的方式获取 iframe
的名称?
您可以使用 selenium
获取 iframe 标签,如下所示:
var iframeElems = driver.findElements(webdriver.By.xpath("//iframe"));
然后在这些元素上循环并获取 name 属性:
iframe.getAttribute('name')
您可以尝试这样的操作:(不确定 JavaScript)
var iframeElems = driver.findElements(webdriver.By.tagName("iframe"));
迭代此列表以获取属性。
for (var f = 0; f < iframeElems.length; f++) {
console.log(iframeElems.getAttribute("attribute name"))
}
这个错误信息...
Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
...意味着 WebDriver 实例 已阻止 访问 cross-origin 框架。
Same-origin 政策
Same-origin policy : Same-origin 策略限制从一个源加载的文档或脚本如何与另一个源的资源交互。它是用于隔离潜在恶意文档的关键安全机制。
Cross-Origin 资源共享 (CORS)
Cross-Origin Resource Sharing (CORS) : Cross-Origin 资源共享 (CORS) 是一种使用额外的 HTTP headers 来告诉 Browser Client 让 AUT(正在测试的应用程序) 运行 在一个来源(域)有权限从不同的服务器访问选定的资源起源。 Web 应用程序在请求具有不同来源(domain
、protocol
和 port
) 比它自己的起源。
来源示例
这是与 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
时,您的 script/program 尝试使用 JavaScript 访问具有不同来源的 <iframe>
,这将是一个巨大的 安全漏洞 如果你能做到的话。如上所述,same-origin 策略 浏览器阻止脚本尝试访问具有不同来源的 <iframe>
。
如果协议、端口(如果指定一个)和主机,则两个页面具有相同的来源 两个网页相同。您有时会看到它被称为 "scheme/host/port tuple"
(其中 "tuple" 是一组由三个组成部分组成的整体)。也许 protocol、domain、hostname 和 port 必须当您想访问所需的框架时,请与您的同一域相同。
解决方案
AUT 可能包含许多 frames / iframes 并且其中一些可能会被加载只有在某些 JavaScript / Ajax 完成后,其中一些可能具有 风格 属性设置为 display:none; 或 visiblity as hidden . Of-course 不需要与所有人互动。因此,识别 <iframe>
的 属性 并进行相应切换将是更好的方法。您可以通过以下方式切换到 <iframe>
:
Frame Name
Frame ID
Frame Index
WebElement
根据最佳实践,当您打算切换到框架时,根据以下参考资料诱导WebDriverWait for frameToBeAvailableAndSwitchToIt。
在这里你可以找到关于Uncaught DOMException
的相关讨论
参考资料
一些参考资料:
在这个讨论中你会找到对SecurityError: Blocked a frame with origin from accessing a cross-origin frame
的详细分析
上的不同方法
在本次讨论的 A Better Approach to Switch Frames
部分,您将找到 How can I select a html element no matter what frame it is in in selenium?
的不同方法
肮脏的解决方案:
对于 windows:
chrome.exe --user-data-dir="" --disable-web-security
对于mac:
open -a Google\ Chrome --args --disable-web-security --user-data-dir=""
这样你打开chrome并让它忽略网络安全。
我试图列出页面中所有 iframe
的名称,以便我可以通过 Selenium 访问它们。
问题是 iframe
的名字每次都变了,所以我需要遍历所有的名字。
我得到:
Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
当我尝试使用以下方法遍历它们时出错:
for (var f = 0; f < window.frames.length; f++) {
console.log(window.frames[f].name)
}
有没有办法以不同的方式获取 iframe
的名称?
您可以使用 selenium
获取 iframe 标签,如下所示:
var iframeElems = driver.findElements(webdriver.By.xpath("//iframe"));
然后在这些元素上循环并获取 name 属性:
iframe.getAttribute('name')
您可以尝试这样的操作:(不确定 JavaScript)
var iframeElems = driver.findElements(webdriver.By.tagName("iframe"));
迭代此列表以获取属性。
for (var f = 0; f < iframeElems.length; f++) {
console.log(iframeElems.getAttribute("attribute name"))
}
这个错误信息...
Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
...意味着 WebDriver 实例 已阻止 访问 cross-origin 框架。
Same-origin 政策
Same-origin policy : Same-origin 策略限制从一个源加载的文档或脚本如何与另一个源的资源交互。它是用于隔离潜在恶意文档的关键安全机制。
Cross-Origin 资源共享 (CORS)
Cross-Origin Resource Sharing (CORS) : Cross-Origin 资源共享 (CORS) 是一种使用额外的 HTTP headers 来告诉 Browser Client 让 AUT(正在测试的应用程序) 运行 在一个来源(域)有权限从不同的服务器访问选定的资源起源。 Web 应用程序在请求具有不同来源(domain
、protocol
和 port
) 比它自己的起源。
来源示例
这是与 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
时,您的 script/program 尝试使用 JavaScript 访问具有不同来源的 <iframe>
,这将是一个巨大的 安全漏洞 如果你能做到的话。如上所述,same-origin 策略 浏览器阻止脚本尝试访问具有不同来源的 <iframe>
。
如果协议、端口(如果指定一个)和主机,则两个页面具有相同的来源 两个网页相同。您有时会看到它被称为 "scheme/host/port tuple"
(其中 "tuple" 是一组由三个组成部分组成的整体)。也许 protocol、domain、hostname 和 port 必须当您想访问所需的框架时,请与您的同一域相同。
解决方案
AUT 可能包含许多 frames / iframes 并且其中一些可能会被加载只有在某些 JavaScript / Ajax 完成后,其中一些可能具有 风格 属性设置为 display:none; 或 visiblity as hidden . Of-course 不需要与所有人互动。因此,识别 <iframe>
的 属性 并进行相应切换将是更好的方法。您可以通过以下方式切换到 <iframe>
:
Frame Name
Frame ID
Frame Index
WebElement
根据最佳实践,当您打算切换到框架时,根据以下参考资料诱导WebDriverWait for frameToBeAvailableAndSwitchToIt。
在这里你可以找到关于Uncaught DOMException
的相关讨论参考资料
一些参考资料:
在这个讨论中你会找到对SecurityError: Blocked a frame with origin from accessing a cross-origin frame
的详细分析
- 上的不同方法
在本次讨论的
A Better Approach to Switch Frames
部分,您将找到 How can I select a html element no matter what frame it is in in selenium? 的不同方法
肮脏的解决方案:
对于 windows:
chrome.exe --user-data-dir="" --disable-web-security
对于mac:
open -a Google\ Chrome --args --disable-web-security --user-data-dir=""
这样你打开chrome并让它忽略网络安全。