1

I don't know what I do wrong but basically. CORS is more than rocket science to me. I tried to make it work with PostMessage but it worked only for Chrome so I gave up on it too. Microsoft Edge did not respond to the eval of the code and Firefox dropped a notice

Only in german the error message of firefox.

Anfrage für Vollbildmodus wurde abgelehnt, weil Element.mozRequestFullScreen() nicht aus einem kurz laufenden Benutzer-generierten Ereignis-Handler aufgerufen wurde.


What I want to do:

Send the "SetFullscreen(1);" Function to an iframe to make it work. The iframe is hosted on a https sub-domain of my site

http://www.spiele-umsonst.de/zombie-derby-2-t6058.html The Full-Screen Button above the game

should execute the same way it would onthe iframe. Simple as that..

https://gameshtml5.spiele-umsonst.de/unitywebgl/zombiederby2/ The iframe has a unity-fullscreen function which can be called SetFullscreen(1);. But I want to call this function on my own button on the parent page.

My faboulous header that I thought would work for the https site:

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 Uncaught DOMException: Blocked a frame with origin "http://www.spiele-umsonst.de" from accessing a cross-origin frame. at fullscreen (http://www.spiele-umsonst.de/zombie-derby-2-t6058.html:589:48) at HTMLDivElement.onclick (http://www.spiele-umsonst.de/zombie-derby-2-t6058.html:418:199)

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
  • See [How to clear the contents of an iFrame from another iFrame](http://stackoverflow.com/questions/33645685/how-to-clear-the-contents-of-an-iframe-from-another-iframe/33649349?s=15|0.0000#33649349) – guest271314 Apr 24 '17 at 18:15
  • Yeah this doesn't seem like a CORS problem but a problem on how you're trying to have an iframe talk to the parent frame. – agmcleod Apr 24 '17 at 19:30
  • I don't understand german, but the FF error looks like it says something along *mozRequestFullscreen must be called by an user's gesture* which means that you can't call it programmatically, from outside of an gesture event flow. – Kaiido Apr 25 '17 at 10:01
  • Also you'll need to set the `allowFullscreen` attribute on the iframe if you want to make one of its elements in fS. – Kaiido Apr 25 '17 at 10:13

3 Answers3

1

The problem you are currently facing has nothing to do with CORS, but with the Fullscreen API's limitation requiring an user-gesture to perform a fullscreenRequest, and with Chrome, which treats the message event synchronously, (yes, this seems to be a chrome bug).

The current workflow is as follow :

  • click frame1. (fullscreen request should be allowed)
  • postMessage frame2. (we're still within the click handler so it should be good too).
  • frame2 handles message event. (This should happen asynchronously, so our click event is broken and the fullscreen request should throw an error.

You can verify this in this plunker which uses synchronous EventTarget.dispatchEvent(event) method, unfortunately, unavailable on cross-origin frames.


Workarounds

If you were loading your iframe from the same domain, you could simply call the element.requestFullscreen() from the main frame, by accessing element through

iframe.contentDocument.querySelector('element').requestFullScreen();

This would work since the click event would not have been broken yet.

You could also use the dispatchEvent trick, but would make no such sense.


But in case of cross-origin frames, I didn't find any way to pass any trusted event from the main frame to the cross-origin one synchronously.

This means that you need to get a second event, this time originating from the framed document itself, to be able to call requestFullscreen on your targeted element. This can be achieved with a splash screen :

plnkr demo

Or you could also only request the fullscreen on the <iframe> element itself, and then change the inner document's style so that your targeted element looks like it was fullscreened.

plnkr demo

Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • recv.contentWindow.dispatchEvent(event); <-- This one causes a CORS-Problem error – Spiele-Umsonst Apr 25 '17 at 21:32
  • @Spiele-Umsonst, that's what I was afraid of... Then you don't have so much solutions... I gave you two more in an edit to my answer, but they're not perfect. – Kaiido Apr 26 '17 at 07:25
0

Like I Said before. I tried postmessage:

This is on the iframe-side

    <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>

and this on the parent-page

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');
        };

This will send the SetFullscreen(1); to the iframe and will than be eval'd. This works fine on chrome, drops a note in firefox as above and does nothing in microsoft edge

  • 1
    Is this an answer ? Otherwise, you may want to add this info as an [edit to your question](https://stackoverflow.com/posts/43595001/edit). – Kaiido Apr 25 '17 at 10:06
  • It's part of an answere that works for chrome. Still waiting if there is someone who can solve one of those cases and can tell the correct solution. – Spiele-Umsonst Apr 25 '17 at 10:43
0

bascially I used another way now. This may not work on every game but on Unity games it works:

Also Thanks to Kaido. This is only a workaround. The main problem to call a function on the iframe failed ;)

  1. I set Fullscreen to the Iframe on the parent

    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. Change the inner width and height of the canvas in it's ratio on resize in the iframe module. Maybe I could just call the SetFullscreen(1); on resize. Don't know if it's mentioned as a user gesture than.

    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));
        }
    }
    

    }