dart-lang / webdev

A CLI for Dart web development.
https://pub.dev/packages/webdev
212 stars 75 forks source link

Use Flutter Web App as iframe in regular html website #2451

Open lunaticcoding opened 5 months ago

lunaticcoding commented 5 months ago

I got the following html code using my flutter web app as an iframe. All the other tickets I found on here reference web sockets.

Here is my html code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Parent Page</title>
    <style>
        html {
            font-size: 16px;
        }
    </style>
    <script type="text/javascript">
        var intervalId;
        var x = 0;

        function sendMessageToIframe() {
            var iframe = document.getElementById("scIframe-5f910afd49fb4e4a92f453d45aff2fc7");
            var p = iframe.contentWindow;

            if (p) {
                intervalId = window.setInterval(function () {
                    x++;
                    if (p) {
                        p.postMessage(JSON.stringify({
                            type: "message",
                            height: 1000,  // Set your desired height here
                            scroll: true
                        }), "*");
                    }
                    if (x > 3) {
                        window.clearInterval(intervalId);
                    }
                }, 100);
            }
        }

        window.addEventListener("message", function(event) {
            if (event.origin !== "http://localhost:58585") {
                return;
            }
            var data;
            try {
                data = JSON.parse(event.data || "{}");
            } catch (e) {
                return;
            }
            if (data.type === "offsetHeight") {
                document.getElementById("scIframe-5f910afd49fb4e4a92f453d45aff2fc7").style.height = data.windowoffset + "px";
            }
        }, false);

        window.onload = sendMessageToIframe;
    </script>
</head>
<body>
<iframe id="scIframe-5f910afd49fb4e4a92f453d45aff2fc7" src="http://localhost:58585/#/" style="border:0; width: 90%;"></iframe>
</body>
</html>

here is my flutter web/index.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="A new Flutter project.">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="apple-mobile-web-app-title" content="tsetme">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">
  <link rel="icon" type="image/png" href="favicon.png"/>
  <title>testme</title>
  <link rel="manifest" href="manifest.json">
  <script type="text/javascript">
    var ALLOWED_ORIGIN = "http://localhost:58585";
    var IFRAMEID = "scIframe-5f910afd49fb4e4a92f453d45aff2fc7";

    function scrollToTop() {
      window.scroll(0, 0);
    }

    function receiveMessage(event) {
      if (event.origin === ALLOWED_ORIGIN) {
        var data;
        try {
          data = JSON.parse(event.data || "{}");
        } catch (e) {
          return;
        }
        if (data && data.type === "message") {
          var iFrame = document.getElementById(IFRAMEID);
          iFrame.style.height = data.height + "px";
          if (data.scroll) {
            scrollToTop();
          }
        }
      }
    }

    function debounce(func, timeout = 100) {
      let timer;
      return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => { func.apply(this, args); }, timeout);
      };
    }

    function scrolling(event) {
      var iframeWin = document.getElementById(IFRAMEID);
      iframeWin.contentWindow.postMessage(
              JSON.stringify({
                type: "offsetHeight",
                screenHeight: window.innerHeight,
                iframeoffset: iframeWin.offsetTop,
                windowoffset: document.body.offsetHeight,
                boundingTop: iframeWin.getBoundingClientRect().top,
              }),
              ALLOWED_ORIGIN
      );
    }

    if (window.addEventListener) {
      window.addEventListener("message", receiveMessage, false);
      window.addEventListener("scroll", debounce(scrolling), false);
    } else if (window.attachEvent) {
      window.attachEvent("onmessage", receiveMessage);
      window.attachEvent("onscroll", debounce(scrolling));
    }
  </script>
  <script async src="flutter_bootstrap.js"></script>
</head>
<body>
</body>
</html>

Unhandled error detected in the injected client.js script.

You can disable this script in webdev by passing --no-injected-client if it is preventing your app from loading, but note that this will also prevent all debugging and hot reload/restart functionality from working.

The original error is below, please file an issue at https://github.com/dart-lang/webdev/issues/new and attach this output:

SecurityError: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "http://localhost:58585" from accessing a cross-origin frame. Error: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "http://localhost:58585" from accessing a cross-origin frame. at Object._launchCommunicationWithDebugExtension (http://localhost:58585/dwds/src/injected/client.js:9694:23) at http://localhost:58585/dwds/src/injected/client.js:25899:17 at _wrapJsFunctionForAsync_closure.$protected (http://localhost:58585/dwds/src/injected/client.js:4049:15) at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:58585/dwds/src/injected/client.js:12422:12) at _awaitOnObject_closure.call$1 (http://localhost:58585/dwds/src/injected/client.js:12410:32) at StaticClosure._rootRunUnary (http://localhost:58585/dwds/src/injected/client.js:4431:18) at _CustomZone.runUnary$2$2 (http://localhost:58585/dwds/src/injected/client.js:13817:39) at _FuturepropagateToListeners_handleValueCallback.call$0 (http://localhost:58585/dwds/src/injected/client.js:12848:51) at Object._FuturepropagateToListeners (http://localhost:58585/dwds/src/injected/client.js:4214:93) at _Future._completeWithValue$1 (http://localhost:58585/dwds/src/injected/client.js:12684:9) at _AsyncAwaitCompleter.complete$1 (http://localhost:58585/dwds/src/injected/client.js:12396:14) at Object._asyncReturn (http://localhost:58585/dwds/src/injected/client.js:4021:17) at http://localhost:58585/dwds/src/injected/client.js:9849:24 at _wrapJsFunctionForAsync_closure.$protected (http://localhost:58585/dwds/src/injected/client.js:4049:15) at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:58585/dwds/src/injected/client.js:12422:12) at _awaitOnObject_closure.call$1 (http://localhost:58585/dwds/src/injected/client.js:12410:32) at StaticClosure._rootRunUnary (http://localhost:58585/dwds/src/injected/client.js:4431:18) at _CustomZone.runUnary$2$2 (http://localhost:58585/dwds/src/injected/client.js:13817:39) at _FuturepropagateToListeners_handleValueCallback.call$0 (http://localhost:58585/dwds/src/injected/client.js:12848:51) at Object._FuturepropagateToListeners (http://localhost:58585/dwds/src/injected/client.js:4214:93) at _Future._completeWithValue$1 (http://localhost:58585/dwds/src/injected/client.js:12684:9) at _AsyncAwaitCompleter.complete$1 (http://localhost:58585/dwds/src/injected/client.js:12396:14) at Object._asyncReturn (http://localhost:58585/dwds/src/injected/client.js:4021:17) at http://localhost:58585/dwds/src/injected/client.js:26515:24 at _wrapJsFunctionForAsync_closure.$protected (http://localhost:58585/dwds/src/injected/client.js:4049:15) at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:58585/dwds/src/injected/client.js:12422:12) at _awaitOnObject_closure.call$1 (http://localhost:58585/dwds/src/injected/client.js:12410:32) at StaticClosure._rootRunUnary (http://localhost:58585/dwds/src/injected/client.js:4431:18) at _CustomZone.runUnary$2$2 (http://localhost:58585/dwds/src/injected/client.js:13817:39) at _FuturepropagateToListeners_handleValueCallback.call$0 (http://localhost:58585/dwds/src/injected/client.js:12848:51) at Object._FuturepropagateToListeners (http://localhost:58585/dwds/src/injected/client.js:4214:93) at _Future._completeWithValue$1 (http://localhost:58585/dwds/src/injected/client.js:12684:9) at _AsyncAwaitCompleter.complete$1 (http://localhost:58585/dwds/src/injected/client.js:12396:14) at Object._asyncReturn (http://localhost:58585/dwds/src/injected/client.js:4021:17) at http://localhost:58585/dwds/src/injected/client.js:26492:24 at _wrapJsFunctionForAsync_closure.$protected (http://localhost:58585/dwds/src/injected/client.js:4049:15) at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:58585/dwds/src/injected/client.js:12422:12) at _awaitOnObject_closure.call$1 (http://localhost:58585/dwds/src/injected/client.js:12410:32) at StaticClosure._rootRunUnary (http://localhost:58585/dwds/src/injected/client.js:4431:18) at _CustomZone.runUnary$2$2 (http://localhost:58585/dwds/src/injected/client.js:13817:39) at _FuturepropagateToListeners_handleValueCallback.call$0 (http://localhost:58585/dwds/src/injected/client.js:12848:51) at Object._FuturepropagateToListeners (http://localhost:58585/dwds/src/injected/client.js:4214:93) at _Future._completeWithValue$1 (http://localhost:58585/dwds/src/injected/client.js:12684:9) at _FutureasyncCompleteWithValue_closure.call$0 (http://localhost:58585/dwds/src/injected/client.js:12788:18) at StaticClosure._rootRun (http://localhost:58585/dwds/src/injected/client.js:4416:16) at _CustomZone.run$1$1 (http://localhost:58585/dwds/src/injected/client.js:13809:39) at _CustomZone.runGuarded$1 (http://localhost:58585/dwds/src/injected/client.js:13752:14) at _CustomZone_bindCallbackGuarded_closure.call$0 (http://localhost:58585/dwds/src/injected/client.js:13947:25) at Object._microtaskLoop (http://localhost:58585/dwds/src/injected/client.js:4275:24) at StaticClosure._startMicrotaskLoop (http://localhost:58585/dwds/src/injected/client.js:4281:11) at _AsyncRuninitializeScheduleImmediate_internalCallback.call$1 (http://localhost:58585/dwds/src/injected/client.js:12299:9)

bkonyi commented 3 months ago

Can you try this without the injected client enabled?