如何解决Chrome 上的 Javascript 跨域异常,但 Firefox 上没有
我最近开发了一个 Firefox 扩展,它允许我在几个网站上自动执行一些操作(主要是检索数据)。
该扩展程序运行良好,因此我目前正在开发该扩展程序的 Chrome 版本。
Chrome 和 Firefox 扩展程序之间存在一些差异,但主要是在两个扩展程序中运行的代码相同。
问题
其中大部分都有效,但是我在使用与 Firefox 扩展程序配合良好的特定网站时遇到了问题。
在此网站上,我试图获取一个位于 iframe 中的表,该表本身又位于另一个 iframe 中。
访问第二个 iframe 时,我面临以下异常。
Uncaught SecurityError: Blocked a frame with origin "https://subdomain.domain.fr" from accessing a frame with origin "https://subdomain.domain.fr". The frame requesting access set "document.domain" to "domain.fr",but the frame being accessed did not. Both must set "document.domain" to the same value to allow access
页面结构如下
<iframe id="iframe_centrale" src="/[...]">
[...]
<iframe id="iframe" src="/[...]">
[...]
<table></table>
[...]
</iframe>
[...]
</iframe>
我正在尝试按如下方式访问 iframe
var tableElement = null;
var iframe = null;
iframe = document.getElementById('iframe_centrale');
if(null != iframe)
{
iframe = iframe.contentwindow.document.getElementById("iframe");
if(null != iframe)
{
tableElement = iframe.contentwindow.document.evaluate("//table",iframe.contentDocument,null,XPathResult.FirsT_ORDERED_NODE_TYPE,null).singleNodeValue;
if((null != tableElement)
{
// Read table
}
}
}
问题分析
当尝试访问位于另一个域上的资源时,通常会遇到被触发的异常。
但是在我的例子中,两个 iframe 都位于同一个域中,因为 src
属性是一个相对 url。
完全相同的代码在 Firefox 中可以正常工作这一事实也证实了我可以访问第二个 iframe。
更多信息
我面临的另一个错误是,在浏览过程中,我填写了一个位于 iframe 中的表单,并且触发了一次以下异常,但表单仍然正确填写。
Uncaught DOMException: Blocked a frame with origin "https://subdomain.domain.fr" from accessing a cross-origin frame.
由于它在一个变异观察者循环中,该指令可能会第二次工作,它可以解释为什么填写表格。
填写表单后,我点击一个按钮,进入 iframe,然后点击进入 iframe。 单击按钮时出现以下异常
Refused to run the JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword,a hash ('sha256-...'),or a nonce ('nonce-...') is required to enable inline execution
再一次,点击变成了一个突变观察者循环,所以它可能被触发一次,然后工作,但我被重定向到下一页,所以点击工作。
从 Firefox 调查
因为我可以从 Firefox 访问两个 iframe 的内容,所以我尝试打印基本文档和两个 iframe 的“域”和“url”信息。
#############################################################
### BASE PAGE : domain.fr / https://subdomain.domain.fr/path1
### IFRAME 1 : domain.fr / https://subdomain.domain.fr/path2
TypeError: iframe2 is null
[...]
#############################################################
### BASE PAGE : domain.fr / https://subdomain.domain.fr/path1
### IFRAME 1 : domain.fr / https://subdomain.domain.fr/path2
### IFRAME 2 : domain.fr / about:blank
[...]
#############################################################
### BASE PAGE : domain.fr / https://subdomain.domain.fr/path1
### IFRAME 1 : domain.fr / https://subdomain.domain.fr/path2
### IFRAME 2 : subdomain.domain.fr / https://subdomain.domain.fr/path3
所以我认为这个问题的发生是因为当 url 从 about:blank
更新到 https://subdomain.domain.fr/path3
时第二个 iframe 改变了它的域
问题
为什么在同一个域/子域中的 iframe 会引发异常?
还有其他方法可以访问第二个 iframe 内容并使用 Chrome 对其进行操作吗?
有人知道为什么这段代码适用于 Firefox 而不适用于 Chrome 吗?
解决方法
错误信息中说明了原因:
The frame requesting access set "document.domain" to "domain.fr",but the frame being
accessed did not. Both must set "document.domain" to the same value to allow access
同源政策基于“tuple origin”术语:scheme
+ host
+ port
+ domain
。起源通常是不可变的,只有元组起源的域可以改变,并且只能通过 document.domain
API(端口号将额外重置为 null)。
原点为 https://subdomain.domain.fr:443
的框架之一将 document.domain
属性设置为 https://domain.fr:null
。
要允许它访问页面上的其他 iframe,您必须将 document.domain = "https://domain.fr"
设置为所有其他 iframe。或者,如果任何 iframe 和主窗口都可以使用 do not touch document.domain
属性。
为什么您的代码在 Firefox 中有效而在 Chrome 中无效,这有点奇怪 - 两种浏览器的最新版本都以相同的方式支持 document.domain
属性。
请注意 document.domain
属性 is deprecated,因此最好尽可能避免使用它。
Refused to run the JavaScript URL
看起来像内容安全策略阻止了 <a href='void(0)'>
结构。它不会阻止链接跟随,只会阻止 javascript 执行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。