CORS - 交叉原点不起作用

时间:2017-04-24 18:10:18

标签: javascript function iframe cors call

我不知道我做错了什么,但基本上。对我来说,CORS不仅仅是火箭科学。 我试图让它与PostMessage一起使用,但它仅适用于Chrome,所以我也放弃了它。 Microsoft Edge没有响应代码的评估,Firefox发布了通知

只有在德语中firefox的错误信息。

  

AnfragefürVollbildmoduswurde abgelehnt,weil   Element.mozRequestFullScreen()nicht aus einem kurz laufenden   Benutzer-generierten Ereignis-Handler aufgerufen wurde。

我想做什么:

发送“SetFullscreen(1);”功能到iframe使其工作。 iframe托管在我网站的https子域

http://www.spiele-umsonst.de/zombie-derby-2-t6058.html游戏上方的全屏按钮

应该以与iframe相同的方式执行。很简单......

https://gameshtml5.spiele-umsonst.de/unitywebgl/zombiederby2/ iframe具有统一全屏功能,可以称为SetFullscreen(1);.但我想在父页面上的我自己的按钮上调用此函数。

我认为可以在https网站上使用的faboulous标题:

Access-Control-Allow-Methods    PUT, GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin *.spiele-umsonst.de
Access-Control-Allow-Credentials    true
Access-Control-Allow-Headers    origin, x-requested-with, content-type
  

zombie-derby-2-t6058.html:589未捕获的DOMException:阻止了一个框架   来源“http://www.spiele-umsonst.de”来访问   跨源框架。       全屏(http://www.spiele-umsonst.de/zombie-derby-2-t6058.html:589:48)       在HTMLDivElement.onclick(http://www.spiele-umsonst.de/zombie-derby-2-t6058.html:418:199

3 个答案:

答案 0 :(得分:1)

您目前面临的问题与CORS无关,但由于Fullscreen API的限制要求用户手势执行fullscreenRequest,而Chrome则同步处理消息事件, (是的,这似乎是一个铬虫)

目前的工作流程如下:

  • 点击frame1。 (应允许全屏请求)
  • postMessage frame2。 (我们仍然在点击处理程序中,所以它也应该是好的。)
  • frame2处理message事件。 (这应该是异步发生的,因此我们的点击事件被破坏,全屏请求应该抛出错误。

您可以在使用同步http://www.w3.org/2001/XMLSchema方法的this plunker中对此进行验证,遗憾的是,这种方法在跨源帧上不可用。

变通方法

如果您从同一个域中加载iframe,只需通过element.requestFullscreen()通过

访问主框架中的element即可
iframe.contentDocument.querySelector('element').requestFullScreen();

这可以工作,因为点击事件还没有被破坏。

您也可以使用dispatchEvent技巧,但没有任何意义。

但是在跨源帧的情况下,我没有找到任何方法将任何EventTarget.dispatchEvent(event)从主帧同步传递到交叉原点。

这意味着您需要获取第二个事件,这次来自框架文档本身,以便能够在您的目标元素上调用requestFullscreen。这可以通过启动画面实现:

trusted event

或者您也可以只在<iframe>元素本身请求全屏,然后更改内部文档的样式,以便您的目标元素看起来像是全屏幕的。

plnkr demo

答案 1 :(得分:0)

像我之前说过的那样。我试过postmessage:

这是在iframe端

    <script>//<![CDATA[
window.onload = function() {
    var messageEle = document.getElementById('message');

    function receiveMessage(e) {
        if (e.origin !== "http://www.spiele-umsonst.de")
            return;
       eval(decodeURI(e.data));
    }
    window.addEventListener('message', receiveMessage);
}
//]]></script>
<div id="message"></div>

,这在父页面上

try{
        var recv = document.getElementById('myid').contentWindow;
        function sendMessage(e) {

        recv.postMessage('SetFullscreen(1);', 'https://gameshtml5.spiele-umsonst.de/unitywebgl/tankscifibattle/');
    }
    sendMessage();
        }
    catch(err){
        console.log('No UnityWebgl found');
        };

这将发送SetFullscreen(1);到iframe并且比eval还要好。 这在chrome上工作正常,在firefox中删除了一个注释,并且在microsoft edge

中什么都不做

答案 2 :(得分:0)

基本上我现在用另一种方式。这可能不适用于每个游戏,但在Unity游戏上可行:

还要感谢Kaido。这只是一种解决方法。在iframe上调用函数的主要问题是失败;)

  1. 我将全屏设置为父

    上的iframe
    var recv = document.getElementById("myid");        
    function toggleFullScreen() {
    if (!document.mozFullScreen && !document.webkitFullScreen) {
      if (recv.mozRequestFullScreen) {
        recv.mozRequestFullScreen();
      } else {
        recv.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
      }
    } else {
      if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else {
        document.webkitCancelFullScreen();
      }
    }   
    } toggleFullScreen();
    
  2. 更改iframe模块中调整大小时画布的内部宽度和高度。也许我可以调用SetFullscreen(1);调整大小。不知道它是否被提及为用户手势而不是。

    window.onresize = function(){
    reportSize();
    document.getElementById('canvas').style.width = newWidth + 'px';
    document.getElementById('canvas').style.height = newHeight + 'px';
    }
    
    function reportSize() {
    realw = document.getElementById('canvas').width;
    realh = document.getElementById('canvas').height;
    myWidth = 0; myHeight = 0; newWidth = 0; newHeight = 0;
    if( typeof( window.innerWidth ) == 'number' ) {
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
    newWidth = myWidth;
    newHeight = Math.round(newWidth*parseInt(realh)/parseInt(realw)); 
    if (newHeight >  myHeight)
        {
        newHeight = myHeight; 
        newWidth = Math.round(newHeight*parseInt(realw)/parseInt(realh));
        }
    }
    

    }