Flutter Web listen to Events posted through iFrame

2,653

To read message data from listener you have to cast event to MessageEvent:

  void listen(html.Event event) {
    var data = (event as html.MessageEvent).data;
    print(data['sender']);
    print(data['message']);
    setState(() {
      //...
    });
  }
Share:
2,653
Jannik
Author by

Jannik

Updated on December 27, 2022

Comments

  • Jannik
    Jannik over 1 year

    my goal is to integrate a flutter widget with the help of an iframe on my main page. The main page is not written in flutter. However, I need an interface through which the main page can communicate with the widget. So I thought of using postMessage() on the main page and html.window.addEventListener() in the flutter widget. Now I am receiving an event inside flutter, but cannot see its content. My temporarily solution is to save the message in local storage and only use the listener as a notifier, but i don't really like this approach. Has anyone a better solution for my problem?

    iFrame Test

    Flutter Test Widget:

    // ignore: avoid_web_libraries_in_flutter
    import 'dart:html' as html;
    import 'package:simple_cookies/simple_cookies.dart';
    
    
     class MessageListener extends StatefulWidget {
          @override
          _MessageListenerState createState() => _MessageListenerState();
      }
    
    class _MessageListenerState extends State<MessageListener> {
      String last;
    
      @override
      void initState() {
        html.window.addEventListener('message', listen, true);
        super.initState();
      }
    
      @override
      void dispose() {
        html.window.removeEventListener('message', listen, true);
        super.dispose();
      }
    
      void listen(html.Event event) {
        last = Cookies.get('iframe_message') ?? 'Error';
        setState(() {});
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('iFrame Test'),
          ),
          body: Center(
            child: SingleChildScrollView(child: Text(last ?? 'No messages yet')),
          ),
        );
      }
    }
    

    main page:

    <html>
    
    <head>
        <title>website title</title>
        <script type="text/javascript">
            function pageProcessing() {
                let messageButton = window.document.getElementById("post_message");
                messageButton.addEventListener("click", () => {
                    let message = window.document.getElementById("message_text").value;
                    window.localStorage.setItem("iframe_message", message);
                    document.getElementById('flutter_widget').contentWindow.postMessage(
                        {
                            sender: "main_page",
                            message: message
                        },
                        "*"
                    );
                });
            }
            window.document.addEventListener('readystatechange', () => {
                if (window.document.readyState == 'complete') {
                    pageProcessing();
                }
            }
            );
        </script>
    </head>
    
    <body>
        <div>
            <input type="text" id="message_text">&nbsp;<input type="button" id="post_message" value="Send Message">
        </div>
        <iframe id="flutter_widget" src="http://testing.orcaf#####"></iframe>
    </body>
    
    </html>