Cri*_*ite 13 html javascript iframe postmessage sandbox
2 postMessage调用测试:1使用星号表示targetOrigin,其中一个使用父文档和子文档的相同https URL.
按钮1:
$('.iframed')[0].contentWindow.postMessage( messageData , '*' );
Run Code Online (Sandbox Code Playgroud)
按钮2:
$('.iframed')[0].contentWindow.postMessage( messageData , 'https://myurl.net' );
Run Code Online (Sandbox Code Playgroud)
父html文档中的iframe元素,指向同一域中的子html文件,位于同一目录中:
<iframe name="childFrame" class="iframed" src="child.html" sandbox="allow-scripts"></iframe>
Run Code Online (Sandbox Code Playgroud)
在单击按钮以触发postMessage之前,两个文档都已完全加载.
==========================================
使用iframe元素如上所述,按钮1对子iframe执行postMessage并成功触发子的postMessage侦听器(尽管它使用了asOisk用于targetOrigin,我不想这样做.)但是,按钮2会产生以下结果控制台中的错误:
"无法在'DOMWindow'上执行'postMessage':提供的目标源(' https://myurl.net ')与收件人窗口的原点('null')不匹配."
==========================================
如果我将"allow-same-origin"添加到iframe的沙箱参数,则两个按钮都会成功传递postMessage数据(按钮2 postMessage调用没有"null"错误,并为targetOrigin提供了url.)但是,我不知道我想这样做,因为我使用iframe的沙盒行为来阻止iframe内容来调用父文档中的js函数.这是一个系统允许"任意"内容(html/js/images/pdfs - 没有像php这样的服务器可执行文件)加载到子iframe中.
也许值得注意的是,iframe内容中的postMessage到父文档的类似按钮工作正常,无论allow-same-origin参数还是asterisk/url的存在:
我陷害按钮1:
parent.postMessage( messageData , 'https://myurl.net' );
Run Code Online (Sandbox Code Playgroud)
iframed按钮2:
parent.postMessage( messageData , '*' );
Run Code Online (Sandbox Code Playgroud)
==========================================
所以,如果我不添加"allow-same-origin"(为什么这个问题不会影响iframe postMessage到父级),为什么postMessage从父级到iframe会导致上面的错误?我尝试将iframe src设置为child.html文档的绝对https网址,但结果是相同的.我还在不同的非ssl-cert服务器位置测试了相同的代码,并且具有相同的结果(所以不要认为它是https贡献...).我必须使用asterisk作为targetOrigin,并且/或者在沙箱参数中使用allow-same-origin?
关于这个问题的其他关于SO的谈话似乎是死路一条,因此希望对解决方案有新的看法......
小智 2
问题是它自己造成的<iframe>,其sandbox属性是:
<iframe name="childFrame" class="iframed" src="child.html" sandbox="allow-scripts"></iframe>
Run Code Online (Sandbox Code Playgroud)
根据 Mozilla 开发者网络关于此元素的文档,以下给出了有关同源策略的问题:
allow-same-origin:如果不使用此令牌,则资源将被视为来自始终不符合同源策略的特殊来源。
您没有指定allow-same-origin,这意味着该帧被视为来自特殊来源,并且postMessage对该帧的调用将失败。
要解决这个问题,只需添加allow-same-origin属性sandbox即可,如下所示:
<!-- 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>
Run Code Online (Sandbox Code Playgroud)
<!-- child.html -->
<script type="text/javascript">
window.onmessage = function(event) {
console.log(event.data);
}
</script>
Run Code Online (Sandbox Code Playgroud)
就是这样!
| 归档时间: |
|
| 查看次数: |
834 次 |
| 最近记录: |