我在我的HTML页面中加载一个<iframe>,并试图使用JavaScript访问其中的元素,但当我尝试执行我的代码时,我得到以下错误:
阻止原点为“http://www.example.com”的帧访问跨原点帧。
如何访问框架中的元素?
我正在使用这段代码进行测试,但徒劳:
$(document).ready(function() {
var iframeWindow = document.getElementById("my-iframe-id").contentWindow;
iframeWindow.addEventListener("load", function() {
var doc = iframe.contentDocument || iframe.contentWindow.document;
var target = doc.getElementById("my-target-id");
target.innerHTML = "Found it!";
});
});
如果你可以控制iframe的内容——也就是说,如果它只是在一个跨起源的设置中加载,比如在Amazon Mechanical Turk上——你可以用<body onload='my_func(my_arg)'>属性来规避这个问题。
例如,对于内部html,使用this html参数(yes -这是定义的,它引用内部主体元素的父窗口):
<身体onload = ' changeForm(这)>
在内部html:
function changeForm(window) {
console.log('inner window loaded: do whatever you want with the inner html');
window.document.getElementById('mturk_form').style.display = 'none';
</script>
实际上,在特定的情况下,有一个变通办法。
如果在同一个域上运行两个进程,但端口不同,那么两个Windows可以不受限制地交互。(即localhost:3000 & localhost:2000)。为了实现这一点,每个窗口都需要将它们的域更改为共享源:
document.domain = 'localhost'
这也适用于您正在使用同一二级域上的不同子域的场景,即您在john.site.example上试图访问peter.site.example或只是site.example
document.domain = 'site.example'
通过显式设置document.domain;浏览器将忽略主机名的差异,Windows可以被视为来自“同源”。现在,在父窗口中,你可以进入iframe:
如果你可以控制iframe的内容——也就是说,如果它只是在一个跨起源的设置中加载,比如在Amazon Mechanical Turk上——你可以用<body onload='my_func(my_arg)'>属性来规避这个问题。
例如,对于内部html,使用this html参数(yes -这是定义的,它引用内部主体元素的父窗口):
<身体onload = ' changeForm(这)>
在内部html:
function changeForm(window) {
console.log('inner window loaded: do whatever you want with the inner html');
window.document.getElementById('mturk_form').style.display = 'none';
</script>
我想添加特定于Java Spring的配置,可以对此产生影响。
在Web站点或网关应用程序中有一个contentSecurityPolicy设置
在Spring中,你可以找到WebSecurityConfigurerAdapter子类的实现
contentSecurityPolicy("
script-src 'self' [URLDomain]/scripts ;
style-src 'self' [URLDomain]/styles;
frame-src 'self' [URLDomain]/frameUrl...
...
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
如果您没有在这里定义安全的外部内容,浏览器将被阻塞。