javascript - postMessage to sandboxed iframe,为什么收件人窗口来源为null? [英] javascript - postMessage to sandboxed iframe, why is recipient window origin null?

查看:174
本文介绍了javascript - postMessage to sandboxed iframe,为什么收件人窗口来源为null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2 postMessage调用测试:1使用asterisk作为targetOrigin,一个使用父文档和子文档的相同https url。

2 postMessage calls in the test: 1 using an asterisk for targetOrigin, one using the same https url of both the parent and child documents.

按钮1:

$('.iframed')[0].contentWindow.postMessage( messageData , '*' );

按钮2:

$('.iframed')[0].contentWindow.postMessage( messageData , 'https://myurl.net' );

父html文档中的iframe元素,它指向同一域上的子html文件,位于同一目录中:

the iframe element in parent html document, which points to child html file on same domain, in same directory:

<iframe name="childFrame" class="iframed" src="child.html" sandbox="allow-scripts"></iframe>

在单击按钮触发postMessage之前,两个文档都已完全加载。

both documents are fully loaded before I am clicking the buttons to trigger postMessage.

========================================= =

==========================================

如上所述编写iframe元素,按钮1对子iframe执行postMessage并成功触发子级的postMessage侦听器(尽管它使用星号表示targetOrigin,我我不想这样做。但是,按钮2会在控制台中导致以下错误:

with iframe element written as above, button 1 performs the postMessage to the child iframe and triggers the child's postMessage listener successfully (though it uses the asterisk for targetOrigin, which I'd prefer not to do.) however, button 2 results in the following error in console:


无法执行'postMessage' 'DOMWindow':提供的目标来源
(' https://myurl.net ')不匹配收件人窗口的
来源('null')。

"Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘https://myurl.net’) does not match the recipient window’s origin (‘null’)."

============ ==============================

==========================================

如果我添加允许 -same-origin到iframe的沙箱参数,然后两个按钮成功传递postMessage数据(使用为targetOrigin提供的url按钮2 postMessage调用没有null错误。)但是,我不想这样做,因为我使用iframe的沙盒行为阻止iframe内容调用js函数父文件。这是一个系统允许任意内容(html / js / images / pdfs - 没有像php这样的服务器可执行文件)加载到子iframe中。

if I add "allow-same-origin" to the iframe's sandbox parameters, both buttons then pass the postMessage data successfully (no "null" error on the button 2 postMessage call with the url provided for the targetOrigin.) however, I don't want to do this, as I am using the iframe's sandboxing behavior to block the iframe content from calling js functions in the parent document. this is for a system allowing "arbitrary" content (html/js/images/pdfs -- nothing server-executable like php though) to be loaded into the child iframe.

也许值得注意的是,iframe内容中的postMessage到父文档的类似按钮工作得很好,无论allow-same-origin参数还是asterisk / url的存在:

perhaps of note, similar buttons inside of the iframe content that postMessage to the parent document work just fine, regardless of the allow-same-origin parameter or the presence of the asterisk/url:

我框架按钮1:

parent.postMessage( messageData , 'https://myurl.net' ); 

iframed按钮2:

iframed button 2:

parent.postMessage( messageData , '*' ); 

===================== =====================

==========================================

那么,为什么postMessage从父代到iframe会导致上面的错误,如果我不添加allow-same-origin(为什么这个问题不会影响iframe postMessage到父级)?我尝试将iframe src设置为child.html文档的绝对https网址,但结果是相同的。我还在不同的非ssl-cert服务器位置测试了相同的代码,并且具有相同的结果(所以不要认为它是https贡献...)。我必须使用asterisk作为targetOrigin,并且/或者在沙箱参数中使用allow-same-origin吗?

so, why does postMessage from the parent to the iframe results in the error above if I don't add "allow-same-origin" (and why does this issue not affect the iframe postMessage to the parent)? I attempted setting the iframe src to an absolute https url to the child.html document, but results were the same. I also tested the same code on a different, non ssl-cert server location, and had the same results (so don't think it is https contributing...). MUST i have EITHER the asterisk as the targetOrigin, AND/OR use allow-same-origin in the sandbox params?

关于此问题的其他对话似乎已经死了 - 结束所以希望对解决方案有新的看法......

other conversations about this issue on SO seem to dead-end so hoping to get a new perspective on a solution...

推荐答案

问题是由< iframe> 本身,其沙箱属性:

The problem is created by the <iframe> itself, with its sandbox attribute:

<iframe name="childFrame" class="iframed" src="child.html" sandbox="allow-scripts"></iframe>

根据Mozilla开发人员网络文档关于此元素,以下给出了有关同源策略的问题:

As per the Mozilla Developer Network documentation on this element, the following gives a problem about same-origin policy:


allow-same-origin :如果未使用此令牌,则资源被视为来自特殊来源总是没有同源政策。

allow-same-origin: If this token is not used, the resource is treated as being from a special origin that always fails the same-origin policy.

你没有指定 allow-same-origin ,这意味着该帧被视为来自特殊原点, postMessage 对该帧的调用将失败。

You didn't specified allow-same-origin, that means the frame is treated as being from a special origin, and postMessage calls to that frame will fail.

要解决此问题,只需将 allow-same-origin 添加到沙箱属性,就像这样:

To solve the problem, just add allow-same-origin to the sandbox attribute, like this:

<!-- index.html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<iframe name="childFrame" class="iframed" src="child.html" sandbox="allow-scripts allow-same-origin"></iframe>
<button class="btn1">A</button>
<button class="btn2">B</button>

<script>
$('.btn1').click(function(event) {
    // This works!
    $('.iframed')[0].contentWindow.postMessage( "something" , '*' );
});
$('.btn2').click(function(event) {
    // This will work too
    $('.iframed')[0].contentWindow.postMessage( "whatever you want" , 'https://myurl.net' );
});
</script>



<!-- child.html -->
<script type="text/javascript">
    window.onmessage = function(event) {
        console.log(event.data);
    }
</script>

就是这样!

这篇关于javascript - postMessage to sandboxed iframe,为什么收件人窗口来源为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆