错误:访问属性“x"的权限被拒绝由于使用 Selenium 的相同/跨源策略? [英] Error: Permission denied to access property "x" due to same/cross origin policy using Selenium?
问题描述
我想访问另一个 HTML 元素内的脚本内容,我可以轻松识别该内容.我试图通过获取父元素然后寻找子元素来找到元素,但我没能做到.
因此,我尝试仅使用 Firefox 中的控制台来获取它,并使用该元素来读取内容,但我无法做到.它看起来像这样:
当我试图对那个元素做任何事情时,我得到了一个指向以下页面的链接和错误:
权限被拒绝访问属性.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Property_access_denied?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default
是否无法访问该对象以使用 selenium 进行自动测试?
此错误信息...
权限被拒绝访问属性.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Property_access_denied?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default
...暗示脚本/程序试图访问您无权访问的对象.这可能是一个 元素从不同的域加载,您违反了同源策略.
同源政策
同源政策限制如何从一个来源加载文档或脚本的关键安全机制可以与来自另一个来源的资源进行交互.它有助于隔离潜在的恶意文档,减少可能的攻击媒介.
起源
如果协议,则两个 URL 具有相同的来源,port(如果指定)和 host 两者都是一样的.您可能会看到这被称为方案/主机/端口元组",或者只是元组".(元组"是一组共同构成一个整体的项目——双重/三重/四重/五重/等的通用形式.)
一个例子
下表给出了与 URL http://store.company.com/dir/page.html
的来源比较示例:
URL 结果原因http://store.company.com/dir2/other.html 成功 只是路径不同http://store.company.com/dir/inner/another.html 成功 只是路径不同https://store.company.com/page.html 失败 不同的协议http://store.company.com:81/dir/page.html 失败 端口不同(http://默认为80端口)http://news.company.com/dir/page.html 故障 不同主机
<块引用>
您还可以找到[文件的来源定义:网址],其中比较复杂.
继承的起源
从带有 about:blank
或 javascript:
URL 的页面执行的脚本继承文档的来源包含该 URL,因为这些类型的 URL 不包含有关源服务器的信息.
例如,about:blank
通常用作父脚本将内容写入其中的新空弹出窗口的 URL(例如,通过 Window.open()
机制).如果此弹出窗口还包含 JavaScript,则该脚本将继承与创建它的脚本相同的来源.
data:
:URL 获得一个新的、空的、安全的上下文.
更改原点
页面可能会更改自己的来源,但有一些限制.脚本可以将 document.domain
的值设置为其当前域或当前域的超域.如果设置为当前域的超级域,则使用较短的超级域进行同源检查.
例如,假设来自 http://store.company.com/dir/other.html
文档的脚本执行以下操作:
document.domain = "company.com";
之后,页面可以通过与 http://company.com/dir/page.html
的同源检查(假设 http://company.com/dir/page.html
设置其文档.域
到 company.com
以表明它希望允许这样做).但是,company.com
可以不将 document.domain
设置为 othercompany.com
,因为那不是超级域company.com
.
端口号由浏览器单独检查.任何对document.domain
的调用,包括document.domain = document.domain
,都会导致端口号被null
覆盖.因此,不能仅通过设置 document.domain = "company.com"
来使 company.com:8080
与 company.com
对话首先.它必须在两者中设置,以便它们的端口号都为空.
注意:当使用 document.domain
允许子域安全访问其父域时,您需要将 document.domain
设置为父域和子域中的值相同.即使这样做只是将父域设置回其原始值,这也是必要的.否则可能会导致权限错误.
解决方案
您需要在切换帧时诱导 WebDriverWait 如下:
Java 示例代码:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id(iframe_id")));
Python 示例代码:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,iframe_id")))
尾声
一些相关的讨论:
I want to access to the content of a script which is inside another HTML element which I can Identify easily. I've tried to find the element by getting the parent and then looking for a child but I've not been able to do it.
So I tried to get it just using the console in firefox and use that element to read the content and I'm not able to do it. It looks like this:
When I tried to do anything with that element I get a link to the following page and error:
Permission denied to access property. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Property_access_denied?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default
Is not possible to access to that object for automatic testing with selenium?
This error message...
Permission denied to access property. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Property_access_denied?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default
...implies that the script/program was attempting to access an object for which you have no permission. This is likely an <iframe>
element loaded from a different domain for which you violated the same-origin policy.
Same-origin policy
The Same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. It helps isolate potentially malicious documents, reducing possible attack vectors.
origin
Two URLs have the same origin if the protocol, port (if specified), and host are the same for both. You may see this referenced as the "scheme/host/port tuple", or just "tuple". (A "tuple" is a set of items that together comprise a whole — a generic form for double/triple/quadruple/quintuple/etc.)
An Example
The following table gives examples of origin comparisons with the URL http://store.company.com/dir/page.html
:
URL Outcome Reason
http://store.company.com/dir2/other.html Success Only the path differs
http://store.company.com/dir/inner/another.html Success Only the path differs
https://store.company.com/page.html Failure Different protocol
http://store.company.com:81/dir/page.html Failure Different port (http:// is port 80 by default)
http://news.company.com/dir/page.html Failure Different host
You can also find [origin definition for file: URLs] where the comparison is more complicated.
Inherited origins
Scripts executed from pages with an about:blank
or javascript:
URL inherit the origin of the document containing that URL, since these types of URLs do not contain information about an origin server.
For example,
about:blank
is often used as a URL of new, empty popup windows into which the parent script writes content (e.g. via theWindow.open()
mechanism). If this popup also contains JavaScript, that script would inherit the same origin as the script that created it.
data:
: URLs get a new, empty, security context.
Changing origin
A page may change its own origin, with some limitations. A script can set the value of document.domain
to its current domain or a superdomain of its current domain. If set to a superdomain of the current domain, the shorter superdomain is used for same-origin checks.
For example, assume a script from the document at http://store.company.com/dir/other.html
executes the following:
document.domain = "company.com";
Afterward, the page can pass the same-origin check with http://company.com/dir/page.html
(assuming http://company.com/dir/page.html
sets its document.domain
to company.com
to indicate that it wishes to allow that). However, company.com
could not set document.domain
to othercompany.com
, since that is not a superdomain of company.com
.
The port number is checked separately by the browser. Any call to document.domain
, including document.domain = document.domain
, causes the port number to be overwritten with null
. Therefore, one cannot make company.com:8080
talk to company.com
by only setting document.domain = "company.com"
in the first. It has to be set in both so their port numbers are both null.
Note: When using
document.domain
to allow a subdomain to access its parent securely, you need to setdocument.domain
to the same value in both the parent domain and the subdomain. This is necessary even if doing so is simply setting the parent domain back to its original value. Failure to do this may result in permission errors.
Solution
You need to induce WebDriverWait while switching frames as follows:
Java sample code:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("iframe_id")));
Python sample code:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"iframe_id")))
Outro
A couple of related discussions:
- Ways to deal with #document under iframe
- Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame while listing the iframes in page
这篇关于错误:访问属性“x"的权限被拒绝由于使用 Selenium 的相同/跨源策略?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!